summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/bind/core_bind.cpp51
-rw-r--r--core/bind/core_bind.h3
-rw-r--r--core/hash_map.h15
-rw-r--r--core/hashfuncs.h4
-rw-r--r--core/math/geometry.h80
-rw-r--r--core/os/main_loop.h3
-rw-r--r--core/os/os.cpp4
-rw-r--r--core/os/os.h2
-rw-r--r--core/variant.cpp10
-rw-r--r--demos/2d/platformer/stage.xml12
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp24
-rw-r--r--drivers/gles2/shaders/copy.glsl63
-rw-r--r--drivers/openssl/stream_peer_openssl.cpp1
-rw-r--r--modules/gdscript/gd_script.cpp1
-rw-r--r--platform/android/os_android.cpp7
-rw-r--r--platform/android/os_android.h2
-rw-r--r--platform/iphone/app_delegate.mm1
-rwxr-xr-xplatform/iphone/gl_view.mm38
-rw-r--r--platform/iphone/os_iphone.cpp6
-rw-r--r--platform/iphone/os_iphone.h2
-rw-r--r--scene/2d/node_2d.cpp28
-rw-r--r--scene/2d/node_2d.h4
-rw-r--r--scene/2d/physics_body_2d.cpp28
-rw-r--r--scene/2d/physics_body_2d.h6
-rw-r--r--scene/2d/ray_cast_2d.cpp17
-rw-r--r--scene/2d/ray_cast_2d.h4
-rw-r--r--scene/2d/tile_map.cpp21
-rw-r--r--scene/2d/tile_map.h4
-rw-r--r--scene/3d/baked_light.cpp7
-rw-r--r--scene/3d/baked_light.h15
-rw-r--r--scene/3d/physics_body.cpp16
-rw-r--r--scene/3d/physics_body.h15
-rw-r--r--scene/3d/visual_instance.h1
-rw-r--r--scene/animation/animation_player.cpp2
-rw-r--r--scene/gui/rich_text_label.cpp4
-rw-r--r--scene/main/viewport.cpp17
-rw-r--r--scene/main/viewport.h4
-rw-r--r--scene/register_scene_types.cpp3
-rw-r--r--scene/resources/environment.cpp3
-rw-r--r--scene/resources/environment.h1
-rw-r--r--scene/resources/mesh.cpp33
-rw-r--r--scene/resources/surface_tool.cpp441
-rw-r--r--scene/resources/surface_tool.h12
-rw-r--r--servers/audio/audio_mixer_sw.cpp194
-rw-r--r--servers/audio/audio_mixer_sw.h19
-rw-r--r--servers/audio/sample_manager_sw.cpp9
-rw-r--r--servers/physics/body_sw.cpp28
-rw-r--r--servers/physics/body_sw.h645
-rw-r--r--servers/physics/physics_server_sw.cpp19
-rw-r--r--servers/physics/physics_server_sw.h3
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp7
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp1
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h4
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp16
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h3
-rw-r--r--servers/physics_2d/space_2d_sw.cpp24
-rw-r--r--servers/physics_2d/space_2d_sw.h10
-rw-r--r--servers/physics_2d_server.cpp8
-rw-r--r--servers/physics_2d_server.h19
-rw-r--r--servers/physics_server.cpp3
-rw-r--r--servers/physics_server.h11
-rw-r--r--servers/visual_server.h2
-rw-r--r--tools/editor/editor_node.cpp5
-rw-r--r--tools/editor/io_plugins/editor_mesh_import_plugin.cpp555
-rw-r--r--tools/editor/io_plugins/editor_mesh_import_plugin.h29
-rw-r--r--tools/editor/io_plugins/editor_sample_import_plugin.cpp178
-rw-r--r--tools/editor/io_plugins/editor_sample_import_plugin.h1
-rw-r--r--tools/editor/plugins/baked_light_editor_plugin.cpp996
-rw-r--r--tools/editor/plugins/baked_light_editor_plugin.h70
-rw-r--r--tools/editor/plugins/sample_editor_plugin.cpp149
-rw-r--r--tools/editor/plugins/sample_library_editor_plugin.cpp2
-rw-r--r--tools/editor/property_editor.cpp12
-rw-r--r--tools/editor/property_editor.h2
73 files changed, 3350 insertions, 689 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index fd6a91d125..ec159da00f 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -479,10 +479,54 @@ void _OS::print_all_textures_by_size() {
print_line(E->get().path+" - "+String::humanize_size(E->get().vram)+" ("+E->get().size+") - total:"+String::humanize_size(total) );
total-=E->get().vram;
}
+}
+void _OS::print_resources_by_type(const Vector<String>& p_types) {
+ Map<String,int> type_count;
+
+ List<Ref<Resource> > resources;
+ ResourceCache::get_cached_resources(&resources);
+
+ List<Ref<Resource> > rsrc;
+ ResourceCache::get_cached_resources(&rsrc);
+
+ for (List<Ref<Resource> >::Element *E=rsrc.front();E;E=E->next()) {
+
+ Ref<Resource> r = E->get();
+
+ bool found = false;
+
+ for (int i=0; i<p_types.size(); i++) {
+ if (r->is_type(p_types[i]))
+ found = true;
+ }
+ if (!found)
+ continue;
+
+ if (!type_count.has(r->get_type())) {
+ type_count[r->get_type()]=0;
+ }
+
+
+ type_count[r->get_type()]++;
+
+ print_line(r->get_type()+": "+r->get_path());
+
+ List<String> metas;
+ r->get_meta_list(&metas);
+ for (List<String>::Element* me = metas.front(); me; me = me->next()) {
+ print_line(" "+String(me->get()) + ": " + r->get_meta(me->get()));
+ };
+ }
+
+ for(Map<String,int>::Element *E=type_count.front();E;E=E->next()) {
+
+ print_line(E->key()+" count: "+itos(E->get()));
+ }
+
+};
-}
void _OS::print_all_resources(const String& p_to_file ) {
@@ -509,9 +553,9 @@ float _OS::get_frames_per_second() const {
return OS::get_singleton()->get_frames_per_second();
}
-Error _OS::native_video_play(String p_path) {
+Error _OS::native_video_play(String p_path, float p_volume) {
- return OS::get_singleton()->native_video_play(p_path);
+ return OS::get_singleton()->native_video_play(p_path, p_volume);
};
bool _OS::native_video_is_playing() {
@@ -614,6 +658,7 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_frames_per_second"),&_OS::get_frames_per_second);
ObjectTypeDB::bind_method(_MD("print_all_textures_by_size"),&_OS::print_all_textures_by_size);
+ ObjectTypeDB::bind_method(_MD("print_resources_by_type"),&_OS::print_resources_by_type);
ObjectTypeDB::bind_method(_MD("native_video_play"),&_OS::native_video_play);
ObjectTypeDB::bind_method(_MD("native_video_is_playing"),&_OS::native_video_is_playing);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index f5c94dcf06..18eb594760 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -98,7 +98,7 @@ public:
bool is_video_mode_resizable(int p_screen=0) const;
Array get_fullscreen_mode_list(int p_screen=0) const;
- Error native_video_play(String p_path);
+ Error native_video_play(String p_path, float p_volume);
bool native_video_is_playing();
void native_video_pause();
void native_video_stop();
@@ -139,6 +139,7 @@ public:
void print_resources_in_use(bool p_short=false);
void print_all_resources(const String& p_to_file);
void print_all_textures_by_size();
+ void print_resources_by_type(const Vector<String>& p_types);
bool has_touchscreen_ui_hint() const;
diff --git a/core/hash_map.h b/core/hash_map.h
index 02a6600c3b..da8f038490 100644
--- a/core/hash_map.h
+++ b/core/hash_map.h
@@ -285,14 +285,12 @@ public:
}
void set( const Pair& p_pair ) {
-
+
+ Entry *e=NULL;
if (!hash_table)
make_hash_table(); // if no table, make one
else
- check_hash_table(); // perform mantenience routine
-
- /* As said, i want to have only one get_entry */
- Entry *e = const_cast<Entry*>( get_entry(p_pair.key) );
+ e = const_cast<Entry*>( get_entry(p_pair.key) );
/* if we made it up to here, the pair doesn't exist, create and assign */
@@ -301,6 +299,7 @@ public:
e=create_entry(p_pair.key);
if (!e)
return;
+ check_hash_table(); // perform mantenience routine
}
e->pair.data = p_pair.data;
@@ -478,12 +477,11 @@ public:
}
inline TData& operator[](const TKey& p_key ) { //assignment
+ Entry *e=NULL;
if (!hash_table)
make_hash_table(); // if no table, make one
else
- check_hash_table(); // perform mantenience routine
-
- Entry *e = const_cast<Entry*>( get_entry(p_key) );
+ e = const_cast<Entry*>( get_entry(p_key) );
/* if we made it up to here, the pair doesn't exist, create */
if (!e) {
@@ -491,6 +489,7 @@ public:
e=create_entry(p_key);
if (!e)
return *(TData*)NULL; /* panic! */
+ check_hash_table(); // perform mantenience routine
}
return e->pair.data;
diff --git a/core/hashfuncs.h b/core/hashfuncs.h
index 6dae82bc55..3b6715a4cd 100644
--- a/core/hashfuncs.h
+++ b/core/hashfuncs.h
@@ -54,9 +54,9 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
return hash;
}
-static inline uint32_t hash_djb2_buffer(uint8_t *p_buff, int p_len) {
+static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len,uint32_t p_prev=5381) {
- uint32_t hash = 5381;
+ uint32_t hash = p_prev;
for(int i=0;i<p_len;i++)
hash = ((hash << 5) + hash) + p_buff[i]; /* hash * 33 + c */
diff --git a/core/math/geometry.h b/core/math/geometry.h
index 826e4697b5..5b21c25bec 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -695,6 +695,86 @@ public:
}
+
+ static inline Vector<Vector3> clip_polygon(const Vector<Vector3>& polygon,const Plane& p_plane) {
+
+ enum LocationCache {
+ LOC_INSIDE=1,
+ LOC_BOUNDARY=0,
+ LOC_OUTSIDE=-1
+ };
+
+ if (polygon.size()==0)
+ return polygon;
+
+ int *location_cache = (int*)alloca(sizeof(int)*polygon.size());
+ int inside_count = 0;
+ int outside_count = 0;
+
+ for (int a = 0; a < polygon.size(); a++) {
+ //float p_plane.d = (*this) * polygon[a];
+ float dist = p_plane.distance_to(polygon[a]);
+ if (dist <-CMP_POINT_IN_PLANE_EPSILON) {
+ location_cache[a] = LOC_INSIDE;
+ inside_count++;
+ } else {
+ if (dist > CMP_POINT_IN_PLANE_EPSILON) {
+ location_cache[a] = LOC_OUTSIDE;
+ outside_count++;
+ } else {
+ location_cache[a] = LOC_BOUNDARY;
+ }
+ }
+ }
+
+ if (outside_count == 0) {
+
+ return polygon; // no changes
+
+ } else if (inside_count == 0) {
+
+ return Vector<Vector3>(); //empty
+ }
+
+// long count = 0;
+ long previous = polygon.size() - 1;
+
+ Vector<Vector3> clipped;
+
+ for (int index = 0; index < polygon.size(); index++) {
+ int loc = location_cache[index];
+ if (loc == LOC_OUTSIDE) {
+ if (location_cache[previous] == LOC_INSIDE) {
+ const Vector3& v1 = polygon[previous];
+ const Vector3& v2 = polygon[index];
+
+ Vector3 segment= v1 - v2;
+ double den=p_plane.normal.dot( segment );
+ double dist=p_plane.distance_to( v1 ) / den;
+ dist=-dist;
+ clipped.push_back( v1 + segment * dist );
+ }
+ } else {
+ const Vector3& v1 = polygon[index];
+ if ((loc == LOC_INSIDE) && (location_cache[previous] == LOC_OUTSIDE)) {
+ const Vector3& v2 = polygon[previous];
+ Vector3 segment= v1 - v2;
+ double den=p_plane.normal.dot( segment );
+ double dist=p_plane.distance_to( v1 ) / den;
+ dist=-dist;
+ clipped.push_back( v1 + segment * dist );
+ }
+
+ clipped.push_back(v1);
+ }
+
+ previous = index;
+ }
+
+ return clipped;
+ }
+
+
static Vector<int> triangulate_polygon(const Vector<Vector2>& p_polygon) {
Vector<int> triangles;
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index b84d2841e1..6eb5881175 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -50,7 +50,8 @@ public:
NOTIFICATION_WM_FOCUS_IN = 5,
NOTIFICATION_WM_FOCUS_OUT = 6,
NOTIFICATION_WM_QUIT_REQUEST = 7,
- NOTIFICATION_WM_UNFOCUS_REQUEST = 8
+ NOTIFICATION_WM_UNFOCUS_REQUEST = 8,
+ NOTIFICATION_OS_MEMORY_WARNING = 9,
};
virtual void input_event( const InputEvent& p_event );
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 65d6ed50b2..11290409d5 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -225,7 +225,7 @@ void OS::print_all_resources(String p_to_file) {
void OS::print_resources_in_use(bool p_short) {
- //ResourceCache::dump(NULL,p_short);
+ ResourceCache::dump(NULL,p_short);
}
void OS::dump_resources_to_file(const char* p_file) {
@@ -438,7 +438,7 @@ int OS::get_processor_count() const {
return 1;
}
-Error OS::native_video_play(String p_path) {
+Error OS::native_video_play(String p_path, float p_volume) {
return FAILED;
};
diff --git a/core/os/os.h b/core/os/os.h
index e7fe0cb09e..24e2b4f2d4 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -321,7 +321,7 @@ public:
virtual String get_unique_ID() const;
- virtual Error native_video_play(String p_path);
+ virtual Error native_video_play(String p_path, float p_volume);
virtual bool native_video_is_playing() const;
virtual void native_video_pause();
virtual void native_video_stop();
diff --git a/core/variant.cpp b/core/variant.cpp
index 6b3b25a103..fdb14c0c0f 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -1337,6 +1337,10 @@ Variant::operator Matrix3() const {
if (type==MATRIX3)
return *_data._matrix3;
+ else if (type==QUAT)
+ return *reinterpret_cast<const Quat*>(_data._mem);
+ else if (type==TRANSFORM)
+ return _data._transform->basis;
else
return Matrix3();
}
@@ -1345,6 +1349,10 @@ Variant::operator Quat() const {
if (type==QUAT)
return *reinterpret_cast<const Quat*>(_data._mem);
+ else if (type==MATRIX3)
+ return *_data._matrix3;
+ else if (type==TRANSFORM)
+ return _data._transform->basis;
else
return Quat();
}
@@ -1357,6 +1365,8 @@ Variant::operator Transform() const {
return *_data._transform;
else if (type==MATRIX3)
return Transform(*_data._matrix3,Vector3());
+ else if (type==QUAT)
+ return Transform(Matrix3(*reinterpret_cast<const Quat*>(_data._mem)),Vector3());
else
return Transform();
}
diff --git a/demos/2d/platformer/stage.xml b/demos/2d/platformer/stage.xml
index cf9a5ff44a..952c21e936 100644
--- a/demos/2d/platformer/stage.xml
+++ b/demos/2d/platformer/stage.xml
@@ -3,15 +3,15 @@
<ext_resource path="res://music.ogg" type="AudioStream"></ext_resource>
<ext_resource path="res://tileset.xml" type="TileSet"></ext_resource>
<ext_resource path="res://coin.xml" type="PackedScene"></ext_resource>
- <ext_resource path="res://player.xml" type="PackedScene"></ext_resource>
+ <ext_resource path="res://seesaw.xml" type="PackedScene"></ext_resource>
<ext_resource path="res://enemy.xml" type="PackedScene"></ext_resource>
<ext_resource path="res://moving_platform.xml" type="PackedScene"></ext_resource>
- <ext_resource path="res://seesaw.xml" type="PackedScene"></ext_resource>
+ <ext_resource path="res://player.xml" type="PackedScene"></ext_resource>
<ext_resource path="res://parallax_bg.xml" type="PackedScene"></ext_resource>
<main_resource>
<dictionary name="_bundled" shared="false">
<string> "names" </string>
- <string_array len="118">
+ <string_array len="119">
<string> "stage" </string>
<string> "Node" </string>
<string> "__meta__" </string>
@@ -28,6 +28,7 @@
<string> "quadrant_size" </string>
<string> "tile_set" </string>
<string> "tile_data" </string>
+ <string> "collision_layers" </string>
<string> "coins" </string>
<string> "coin" </string>
<string> "Area2D" </string>
@@ -138,7 +139,7 @@
<string> "node_count" </string>
<int> 66 </int>
<string> "variants" </string>
- <array len="95" shared="false">
+ <array len="96" shared="false">
<dictionary shared="false">
<string> "__editor_plugin_states__" </string>
<dictionary shared="false">
@@ -260,6 +261,7 @@
<int> 16 </int>
<resource resource_type="TileSet" path="res://tileset.xml"> </resource>
<int_array len="1998"> 0, 2, 70, 536870914, 71, 10, 72, 10, 73, 10, 74, 10, 75, 10, 76, 10, 77, 10, 78, 10, 65536, 2, 65606, 536870914, 65607, 10, 65608, 10, 65609, 10, 65610, 10, 65611, 10, 65612, 10, 65613, 10, 65614, 10, 131072, 2, 131142, 536870914, 131143, 10, 131144, 10, 131145, 10, 131146, 10, 131147, 10, 131148, 10, 131149, 10, 131150, 10, 196608, 2, 196626, 9, 196678, 536870914, 196679, 10, 196680, 10, 196681, 10, 196682, 10, 196683, 10, 196684, 10, 196685, 10, 196686, 10, 262144, 2, 262162, 8, 262214, 536870914, 262215, 10, 262216, 10, 262217, 10, 262218, 10, 262219, 10, 262220, 10, 262221, 10, 262222, 10, 327680, 2, 327697, 536870921, 327698, 7, 327733, 9, 327750, 536870914, 327751, 10, 327752, 10, 327753, 10, 327754, 10, 327755, 10, 327756, 10, 327757, 10, 327758, 10, 393216, 2, 393233, 536870920, 393234, 7, 393257, 9, 393269, 7, 393286, 536870914, 393287, 10, 393288, 10, 393289, 10, 393290, 10, 393291, 10, 393292, 10, 393293, 10, 393294, 10, 458752, 2, 458769, 7, 458770, 8, 458790, 9, 458793, 8, 458805, 8, 458822, 536870914, 458823, 10, 458824, 10, 458825, 10, 458826, 10, 458827, 10, 458828, 10, 458829, 10, 458830, 10, 524288, 4, 524289, 1, 524304, 536870913, 524305, 536870918, 524306, 6, 524307, 5, 524308, 1, 524326, 8, 524329, 7, 524341, 7, 524358, 536870914, 524359, 10, 524360, 10, 524361, 10, 524362, 10, 524363, 10, 524364, 10, 524365, 10, 524366, 10, 589824, 10, 589825, 13, 589840, 536870914, 589841, 10, 589842, 10, 589843, 10, 589844, 2, 589862, 7, 589865, 7, 589876, 536870913, 589877, 6, 589878, 1, 589894, 536870914, 589895, 10, 589896, 10, 589897, 10, 589898, 10, 589899, 10, 589900, 10, 589901, 10, 589902, 10, 655360, 2, 655376, 536870914, 655377, 10, 655378, 10, 655379, 10, 655380, 2, 655398, 7, 655401, 8, 655412, 536870925, 655413, 11, 655414, 13, 655430, 536870914, 655431, 10, 655432, 10, 655433, 10, 655434, 10, 655435, 10, 655436, 10, 655437, 10, 655438, 10, 720896, 2, 720912, 536870914, 720913, 10, 720914, 10, 720915, 10, 720916, 2, 720934, 8, 720937, 7, 720958, 536870913, 720959, 5, 720960, 536870917, 720961, 5, 720962, 5, 720963, 536870917, 720964, 5, 720965, 0, 720966, 536870916, 720967, 10, 720968, 10, 720969, 10, 720970, 10, 720971, 10, 720972, 10, 720973, 10, 720974, 10, 786432, 2, 786437, 9, 786448, 536870914, 786449, 10, 786450, 10, 786451, 10, 786452, 2, 786464, 536870913, 786465, 1, 786470, 7, 786473, 7, 786474, 536870924, 786475, 1, 786494, 536870914, 786495, 10, 786496, 10, 786497, 10, 786498, 10, 786499, 10, 786500, 10, 786501, 10, 786502, 10, 786503, 10, 786504, 10, 786505, 10, 786506, 10, 786507, 10, 786508, 10, 786509, 10, 851968, 2, 851973, 7, 851984, 536870914, 851985, 10, 851986, 10, 851987, 10, 851988, 2, 851996, 536870913, 851997, 1, 852000, 536870914, 852001, 3, 852006, 7, 852009, 536870913, 852011, 2, 852030, 536870914, 852031, 10, 852032, 10, 852033, 10, 852034, 10, 852035, 10, 852036, 10, 852037, 10, 852038, 10, 852039, 10, 852040, 10, 852041, 10, 852042, 10, 852043, 10, 852044, 10, 852045, 10, 917504, 2, 917506, 9, 917509, 7, 917512, 536870921, 917520, 536870925, 917521, 11, 917522, 11, 917523, 11, 917524, 13, 917532, 536870925, 917533, 13, 917536, 536870914, 917537, 4, 917538, 1, 917540, 536870913, 917541, 0, 917542, 1, 917545, 536870914, 917546, 10, 917547, 4, 917548, 1, 917566, 536870914, 917567, 10, 917568, 10, 917569, 10, 917570, 10, 917571, 10, 917572, 10, 917573, 10, 917574, 10, 917575, 10, 917576, 10, 917577, 10, 917578, 10, 917579, 10, 917580, 10, 917581, 10, 983040, 2, 983042, 7, 983045, 7, 983048, 536870920, 983050, 536870913, 983051, 1, 983064, 536870913, 983065, 1, 983072, 536870914, 983073, 10, 983074, 4, 983075, 0, 983076, 536870916, 983077, 10, 983078, 4, 983079, 536870912, 983080, 536870912, 983081, 536870916, 983082, 10, 983083, 10, 983084, 2, 983095, 9, 983102, 536870914, 983103, 10, 983104, 10, 983105, 10, 983106, 10, 983107, 10, 983108, 10, 983109, 10, 983110, 10, 983111, 10, 983112, 10, 983113, 10, 983114, 10, 983115, 10, 983116, 10, 983117, 10, 1048576, 2, 1048578, 8, 1048581, 8, 1048584, 536870919, 1048586, 536870925, 1048587, 13, 1048600, 536870925, 1048601, 13, 1048604, 9, 1048608, 536870925, 1048609, 536870923, 1048610, 536870923, 1048611, 536870923, 1048612, 10, 1048613, 10, 1048614, 10, 1048615, 10, 1048616, 10, 1048617, 10, 1048618, 10, 1048619, 10, 1048620, 4, 1048621, 1, 1048630, 536870921, 1048631, 8, 1048638, 536870914, 1048639, 10, 1048640, 10, 1048641, 10, 1048642, 10, 1048643, 10, 1048644, 10, 1048645, 10, 1048646, 10, 1048647, 10, 1048648, 10, 1048649, 10, 1048650, 10, 1048651, 10, 1048652, 10, 1048653, 10, 1114112, 4, 1114113, 0, 1114114, 6, 1114115, 0, 1114116, 0, 1114117, 6, 1114118, 1, 1114120, 536870920, 1114128, 536870913, 1114129, 5, 1114130, 536870917, 1114131, 5, 1114132, 0, 1114133, 1, 1114140, 7, 1114141, 536870921, 1114148, 536870914, 1114149, 10, 1114150, 10, 1114151, 10, 1114152, 10, 1114153, 10, 1114154, 10, 1114155, 10, 1114156, 10, 1114157, 2, 1114166, 536870920, 1114167, 8, 1114174, 536870914, 1114175, 10, 1114176, 10, 1114177, 10, 1114178, 10, 1114179, 10, 1114180, 10, 1114181, 10, 1114182, 10, 1114183, 10, 1114184, 10, 1114185, 10, 1114186, 10, 1114187, 10, 1114188, 10, 1179648, 10, 1179649, 10, 1179650, 10, 1179651, 10, 1179652, 10, 1179653, 10, 1179654, 2, 1179656, 536870919, 1179663, 536870915, 1179665, 10, 1179666, 10, 1179667, 10, 1179668, 10, 1179669, 4, 1179670, 12, 1179675, 9, 1179676, 8, 1179677, 8, 1179684, 536870914, 1179685, 10, 1179686, 10, 1179687, 10, 1179688, 10, 1179689, 10, 1179690, 10, 1179691, 10, 1179692, 10, 1179693, 4, 1179694, 1, 1179701, 9, 1179702, 536870919, 1179703, 7, 1179710, 536870914, 1179711, 10, 1179712, 10, 1179713, 10, 1179714, 10, 1179715, 10, 1179716, 10, 1179717, 10, 1179718, 10, 1179719, 10, 1179720, 10, 1179721, 10, 1179722, 10, 1245184, 10, 1245185, 10, 1245186, 10, 1245187, 10, 1245188, 10, 1245189, 10, 1245190, 2, 1245192, 536870919, 1245199, 536870913, 1245200, 536870916, 1245201, 10, 1245202, 10, 1245203, 10, 1245204, 10, 1245205, 10, 1245207, 1, 1245211, 7, 1245212, 7, 1245213, 536870920, 1245220, 536870914, 1245221, 10, 1245222, 10, 1245223, 10, 1245224, 10, 1245225, 10, 1245226, 10, 1245227, 10, 1245228, 10, 1245229, 10, 1245230, 2, 1245237, 8, 1245238, 536870919, 1245239, 8, 1245240, 536870921, 1245246, 536870914, 1245247, 10, 1245248, 10, 1245249, 10, 1245250, 10, 1245251, 10, 1245252, 10, 1245253, 10, 1245254, 10, 1245255, 10, 1245256, 10, 1245257, 10, 1245258, 10, 1310720, 10, 1310721, 10, 1310722, 10, 1310723, 10, 1310724, 10, 1310725, 10, 1310726, 2, 1310728, 536870920, 1310730, 536870913, 1310731, 1, 1310734, 536870913, 1310735, 536870916, 1310736, 10, 1310737, 10, 1310738, 10, 1310739, 10, 1310740, 10, 1310741, 10, 1310742, 10, 1310743, 4, 1310744, 1, 1310747, 8, 1310748, 7, 1310749, 536870919, 1310756, 536870914, 1310757, 10, 1310758, 10, 1310759, 10, 1310760, 10, 1310761, 10, 1310762, 10, 1310763, 10, 1310764, 10, 1310765, 10, 1310766, 4, 1310767, 5, 1310768, 12, 1310773, 7, 1310774, 536870919, 1310775, 7, 1310776, 536870919, 1310782, 536870914, 1310783, 10, 1310784, 10, 1310785, 10, 1310786, 10, 1310787, 10, 1310788, 10, 1310789, 10, 1310790, 10, 1310791, 10, 1310792, 10, 1310793, 10, 1376256, 10, 1376257, 10, 1376258, 10, 1376259, 10, 1376260, 10, 1376261, 10, 1376262, 4, 1376263, 0, 1376264, 536870918, 1376265, 0, 1376266, 536870916, 1376267, 4, 1376268, 0, 1376269, 0, 1376270, 536870916, 1376271, 10, 1376272, 10, 1376273, 10, 1376274, 10, 1376275, 10, 1376276, 10, 1376277, 10, 1376278, 10, 1376279, 10, 1376280, 4, 1376281, 12, 1376283, 8, 1376284, 8, 1376285, 536870920, 1376287, 536870924, 1376288, 0, 1376289, 5, 1376290, 536870917, 1376291, 0, 1376292, 536870916, 1376293, 10, 1376294, 10, 1376295, 10, 1376296, 10, 1376297, 10, 1376298, 10, 1376299, 10, 1376300, 10, 1376301, 10, 1376302, 10, 1376303, 10, 1376305, 12, 1376309, 7, 1376310, 536870920, 1376311, 7, 1376312, 536870920, 1376318, 536870914, 1376319, 10, 1376320, 10, 1376321, 10, 1376322, 10, 1376323, 10, 1376324, 10, 1376325, 10, 1376326, 10, 1376327, 10, 1376328, 10, 1441792, 10, 1441793, 10, 1441794, 10, 1441795, 10, 1441796, 10, 1441797, 10, 1441798, 10, 1441799, 10, 1441800, 10, 1441801, 10, 1441802, 10, 1441803, 10, 1441804, 10, 1441805, 10, 1441806, 10, 1441807, 10, 1441808, 10, 1441809, 10, 1441810, 10, 1441811, 10, 1441812, 10, 1441813, 10, 1441814, 10, 1441815, 10, 1441816, 10, 1441818, 0, 1441819, 6, 1441820, 6, 1441821, 536870918, 1441822, 5, 1441824, 10, 1441825, 10, 1441826, 10, 1441827, 10, 1441828, 10, 1441829, 10, 1441830, 10, 1441831, 10, 1441832, 10, 1441833, 10, 1441834, 10, 1441835, 10, 1441836, 10, 1441837, 10, 1441838, 10, 1441839, 10, 1441840, 10, 1441842, 0, 1441843, 0, 1441844, 0, 1441845, 6, 1441846, 536870918, 1441847, 6, 1441848, 536870918, 1441849, 0, 1441850, 5, 1441851, 536870917, 1441852, 5, 1441853, 0, 1441854, 536870916, 1441855, 10, 1441856, 10, 1441857, 10, 1441858, 10, 1441859, 10, 1441860, 10, 1441861, 10, 1441862, 10, 1441863, 10, 1507328, 10, 1507329, 10, 1507330, 10, 1507331, 10, 1507332, 10, 1507333, 10, 1507334, 10, 1507335, 10, 1507336, 10, 1507337, 10, 1507338, 10, 1507339, 10, 1507340, 10, 1507341, 10, 1507342, 10, 1507343, 10, 1507344, 10, 1507345, 10, 1507346, 10, 1507347, 10, 1507348, 10, 1507349, 10, 1507350, 10, 1507351, 10, 1507352, 10, 1507353, 10, 1507354, 10, 1507355, 10, 1507356, 10, 1507357, 10, 1507358, 10, 1507359, 10, 1507360, 10, 1507361, 10, 1507362, 10, 1507363, 10, 1507364, 10, 1507365, 10, 1507366, 10, 1507367, 10, 1507368, 10, 1507369, 10, 1507370, 10, 1507371, 10, 1507372, 10, 1507373, 10, 1507374, 10, 1507375, 10, 1507376, 10, 1507377, 10, 1507378, 10, 1507379, 10, 1507380, 10, 1507381, 10, 1507382, 10, 1507383, 10, 1507384, 10, 1507385, 10, 1507386, 10, 1507387, 10, 1507388, 10, 1507389, 10, 1507390, 10, 1507391, 10, 1507392, 10, 1507393, 10, 1507394, 10, 1507395, 10, 1507396, 10, 1507397, 10, 1507398, 10, 1507399, 10, 1572864, 10, 1572865, 10, 1572866, 10, 1572867, 10, 1572868, 10, 1572869, 10, 1572870, 10, 1572871, 10, 1572872, 10, 1572873, 10, 1572874, 10, 1572875, 10, 1572876, 10, 1572877, 10, 1572878, 10, 1572879, 10, 1572880, 10, 1572881, 10, 1572882, 10, 1572883, 10, 1572884, 10, 1572885, 10, 1572886, 10, 1572887, 10, 1572888, 10, 1572889, 10, 1572890, 10, 1572891, 10, 1572892, 10, 1572893, 10, 1572894, 10, 1572895, 10, 1572896, 10, 1572897, 10, 1572898, 10, 1572899, 10, 1572900, 10, 1572901, 10, 1572902, 10, 1572903, 10, 1572904, 10, 1572905, 10, 1572906, 10, 1572907, 10, 1572908, 10, 1572909, 10, 1572910, 10, 1572911, 10, 1572912, 10, 1572913, 10, 1572914, 10, 1572915, 10, 1572916, 10, 1572917, 10, 1572918, 10, 1572919, 10, 1572920, 10, 1572921, 10, 1572922, 10, 1572923, 10, 1572924, 10, 1572925, 10, 1572926, 10, 1572927, 10, 1572928, 10, 1572929, 10, 1572930, 10, 1572931, 10, 1572932, 10, 1572933, 10, 1572934, 10, 1572935, 10, 1638400, 10, 1638401, 10, 1638402, 10, 1638403, 10, 1638404, 10, 1638405, 10, 1638406, 10, 1638407, 10, 1638408, 10, 1638409, 10, 1638410, 10, 1638411, 10, 1638412, 10, 1638413, 10, 1638414, 10, 1638415, 10, 1638416, 10, 1638417, 10, 1638418, 10, 1638419, 10, 1638420, 10, 1638421, 10, 1638422, 10, 1638423, 10, 1638424, 10, 1638425, 10, 1638426, 10, 1638427, 10, 1638428, 10, 1638429, 10, 1638430, 10, 1638431, 10, 1638432, 10, 1638433, 10, 1638434, 10, 1638435, 10, 1638436, 10, 1638437, 10, 1638438, 10, 1638439, 10, 1638440, 10, 1638441, 10, 1638442, 10, 1638443, 10, 1638444, 10, 1638445, 10, 1638446, 10, 1638447, 10, 1638448, 10, 1638449, 10, 1638450, 10, 1638451, 10, 1638452, 10, 1638453, 10, 1638454, 10, 1638455, 10, 1638456, 10, 1638457, 10, 1638458, 10, 1638459, 10, 1638460, 10, 1638461, 10, 1638462, 10, 1638463, 10, 1638464, 10, 1638465, 10, 1638466, 10, 1638467, 10, 1638468, 10, 1638469, 10, 1638470, 10, 1638471, 10, 1703952, 10, 1703953, 10, 1703954, 10, 1703955, 10, 1703956, 10, 1703957, 10, 1703958, 10, 1703959, 10, 1703960, 10, 1703961, 10, 1703962, 10, 1703963, 10, 1703964, 10, 1703965, 10, 1703966, 10, 1703967, 10, 1703968, 10, 1703969, 10, 1703970, 10, 1703971, 10, 1703972, 10, 1703973, 10, 1703974, 10, 1703975, 10, 1703976, 10, 1703977, 10, 1703978, 10, 1703979, 10, 1703980, 10, 1703981, 10, 1703982, 10, 1703983, 10, 1703984, 10, 1703985, 10, 1703986, 10, 1703987, 10, 1703988, 10, 1703989, 10, 1703990, 10, 1703991, 10, 1703992, 10, 1703993, 10, 1703994, 10, 1703995, 10, 1703996, 10, 1703997, 10, 1703998, 10, 1703999, 10, 1704000, 10, 1704001, 10, 1704002, 10, 1704003, 10, 1704004, 10, 1704005, 10, 1704006, 10, 1704007, 10, 1769488, 10, 1769489, 10, 1769490, 10, 1769491, 10, 1769492, 10, 1769493, 10, 1769494, 10, 1769495, 10, 1769496, 10, 1769497, 10, 1769498, 10, 1769499, 10, 1769500, 10, 1769501, 10, 1769502, 10, 1769503, 10, 1769504, 10, 1769505, 10, 1769506, 10, 1769507, 10, 1769508, 10, 1769509, 10, 1769510, 10, 1769511, 10, 1769512, 10, 1769513, 10, 1769514, 10, 1769515, 10, 1769516, 10, 1769517, 10, 1769518, 10, 1769519, 10, 1769520, 10, 1769521, 10, 1769522, 10, 1769523, 10, 1769524, 10, 1769525, 10, 1769526, 10, 1769527, 10, 1769528, 10, 1769529, 10, 1769530, 10, 1769531, 10, 1769532, 10, 1769533, 10, 1769534, 10, 1769535, 10, 1769536, 10, 1769537, 10, 1769538, 10, 1769539, 10, 1769540, 10, 1769541, 10 </int_array>
+ <int> 1 </int>
<dictionary shared="false">
<string> "_edit_lock_" </string>
<bool> True </bool>
@@ -352,7 +354,7 @@
<real> -1 </real>
</array>
<string> "nodes" </string>
- <int_array len="688"> -1, -1, 1, 0, -1, 1, 2, 0, 0, 0, 0, 4, 3, -1, 12, 5, 1, 6, 2, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12, 7, 13, 8, 14, 9, 15, 10, 2, 11, 0, 0, 0, 1, 16, -1, 1, 2, 12, 0, 2, 0, 18, 17, 13, 1, 9, 14, 0, 2, 0, 18, 19, 13, 1, 9, 15, 0, 2, 0, 18, 20, 13, 1, 9, 16, 0, 2, 0, 18, 21, 13, 1, 9, 17, 0, 2, 0, 18, 22, 13, 1, 9, 18, 0, 2, 0, 18, 23, 13, 1, 9, 19, 0, 2, 0, 18, 24, 13, 1, 9, 20, 0, 2, 0, 18, 25, 13, 1, 9, 21, 0, 2, 0, 18, 26, 13, 1, 9, 22, 0, 2, 0, 18, 27, 13, 1, 9, 23, 0, 2, 0, 18, 28, 13, 1, 9, 24, 0, 2, 0, 18, 29, 13, 1, 9, 25, 0, 2, 0, 18, 30, 13, 1, 9, 26, 0, 2, 0, 18, 31, 13, 1, 9, 27, 0, 2, 0, 18, 32, 13, 1, 9, 28, 0, 2, 0, 18, 33, 13, 1, 9, 29, 0, 2, 0, 18, 34, 13, 1, 9, 30, 0, 2, 0, 18, 35, 13, 1, 9, 31, 0, 2, 0, 18, 36, 13, 1, 9, 32, 0, 2, 0, 18, 37, 13, 1, 9, 33, 0, 2, 0, 18, 38, 13, 1, 9, 34, 0, 2, 0, 18, 39, 13, 1, 9, 35, 0, 2, 0, 18, 40, 13, 1, 9, 36, 0, 2, 0, 18, 41, 13, 1, 9, 37, 0, 2, 0, 18, 42, 13, 1, 9, 38, 0, 2, 0, 18, 43, 13, 1, 9, 39, 0, 2, 0, 18, 44, 13, 1, 9, 40, 0, 2, 0, 18, 45, 13, 1, 9, 41, 0, 2, 0, 18, 46, 13, 1, 9, 42, 0, 2, 0, 18, 47, 13, 1, 9, 43, 0, 2, 0, 18, 48, 13, 1, 9, 44, 0, 2, 0, 18, 49, 13, 1, 9, 45, 0, 2, 0, 18, 50, 13, 1, 9, 46, 0, 2, 0, 18, 51, 13, 1, 9, 47, 0, 2, 0, 18, 52, 13, 1, 9, 48, 0, 2, 0, 18, 53, 13, 1, 9, 49, 0, 2, 0, 18, 54, 13, 1, 9, 50, 0, 2, 0, 18, 55, 13, 1, 9, 51, 0, 2, 0, 18, 56, 13, 1, 9, 52, 0, 2, 0, 18, 57, 13, 1, 9, 53, 0, 2, 0, 18, 58, 13, 1, 9, 54, 0, 2, 0, 18, 59, 13, 1, 9, 55, 0, 0, 0, 61, 60, 56, 1, 9, 57, 0, 0, 0, 1, 62, -1, 0, 0, 46, 0, 64, 63, 58, 3, 9, 59, 65, 60, 66, 61, 0, 46, 0, 64, 67, 58, 3, 9, 62, 65, 63, 66, 64, 0, 46, 0, 64, 68, 58, 3, 9, 65, 65, 66, 66, 64, 0, 46, 0, 64, 69, 67, 1, 9, 68, 0, 0, 0, 71, 70, -1, 6, 72, 69, 73, 3, 74, 1, 75, 70, 76, 1, 77, 3, 0, 0, 0, 1, 78, -1, 0, 0, 52, 0, 61, 79, 71, 1, 9, 72, 0, 52, 0, 61, 80, 71, 1, 9, 73, 0, 52, 0, 61, 81, 71, 1, 9, 74, 0, 52, 0, 61, 82, 71, 1, 9, 75, 0, 52, 0, 61, 83, 71, 1, 9, 76, 0, 52, 0, 61, 84, 71, 1, 9, 77, 0, 52, 0, 61, 85, 71, 1, 9, 78, 0, 52, 0, 61, 86, 71, 1, 9, 79, 0, 52, 0, 61, 87, 71, 1, 9, 80, 0, 52, 0, 61, 88, 71, 1, 9, 81, 0, 52, 0, 61, 89, 71, 1, 9, 82, 0, 0, 0, 91, 90, 83, 0, 0, 0, 0, 92, 92, -1, 29, 5, 1, 6, 2, 7, 2, 8, 3, 93, 84, 94, 85, 95, 86, 96, 87, 97, 88, 98, 88, 99, 88, 100, 88, 101, 1, 102, 1, 103, 89, 104, 2, 105, 5, 106, 90, 107, 2, 108, 91, 109, 5, 110, 3, 111, 3, 112, 92, 113, 93, 114, 93, 115, 1, 116, 3, 117, 94, 0 </int_array>
+ <int_array len="690"> -1, -1, 1, 0, -1, 1, 2, 0, 0, 0, 0, 4, 3, -1, 13, 5, 1, 6, 2, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12, 7, 13, 8, 14, 9, 15, 10, 16, 11, 2, 12, 0, 0, 0, 1, 17, -1, 1, 2, 13, 0, 2, 0, 19, 18, 14, 1, 9, 15, 0, 2, 0, 19, 20, 14, 1, 9, 16, 0, 2, 0, 19, 21, 14, 1, 9, 17, 0, 2, 0, 19, 22, 14, 1, 9, 18, 0, 2, 0, 19, 23, 14, 1, 9, 19, 0, 2, 0, 19, 24, 14, 1, 9, 20, 0, 2, 0, 19, 25, 14, 1, 9, 21, 0, 2, 0, 19, 26, 14, 1, 9, 22, 0, 2, 0, 19, 27, 14, 1, 9, 23, 0, 2, 0, 19, 28, 14, 1, 9, 24, 0, 2, 0, 19, 29, 14, 1, 9, 25, 0, 2, 0, 19, 30, 14, 1, 9, 26, 0, 2, 0, 19, 31, 14, 1, 9, 27, 0, 2, 0, 19, 32, 14, 1, 9, 28, 0, 2, 0, 19, 33, 14, 1, 9, 29, 0, 2, 0, 19, 34, 14, 1, 9, 30, 0, 2, 0, 19, 35, 14, 1, 9, 31, 0, 2, 0, 19, 36, 14, 1, 9, 32, 0, 2, 0, 19, 37, 14, 1, 9, 33, 0, 2, 0, 19, 38, 14, 1, 9, 34, 0, 2, 0, 19, 39, 14, 1, 9, 35, 0, 2, 0, 19, 40, 14, 1, 9, 36, 0, 2, 0, 19, 41, 14, 1, 9, 37, 0, 2, 0, 19, 42, 14, 1, 9, 38, 0, 2, 0, 19, 43, 14, 1, 9, 39, 0, 2, 0, 19, 44, 14, 1, 9, 40, 0, 2, 0, 19, 45, 14, 1, 9, 41, 0, 2, 0, 19, 46, 14, 1, 9, 42, 0, 2, 0, 19, 47, 14, 1, 9, 43, 0, 2, 0, 19, 48, 14, 1, 9, 44, 0, 2, 0, 19, 49, 14, 1, 9, 45, 0, 2, 0, 19, 50, 14, 1, 9, 46, 0, 2, 0, 19, 51, 14, 1, 9, 47, 0, 2, 0, 19, 52, 14, 1, 9, 48, 0, 2, 0, 19, 53, 14, 1, 9, 49, 0, 2, 0, 19, 54, 14, 1, 9, 50, 0, 2, 0, 19, 55, 14, 1, 9, 51, 0, 2, 0, 19, 56, 14, 1, 9, 52, 0, 2, 0, 19, 57, 14, 1, 9, 53, 0, 2, 0, 19, 58, 14, 1, 9, 54, 0, 2, 0, 19, 59, 14, 1, 9, 55, 0, 2, 0, 19, 60, 14, 1, 9, 56, 0, 0, 0, 62, 61, 57, 1, 9, 58, 0, 0, 0, 1, 63, -1, 0, 0, 46, 0, 65, 64, 59, 3, 9, 60, 66, 61, 67, 62, 0, 46, 0, 65, 68, 59, 3, 9, 63, 66, 64, 67, 65, 0, 46, 0, 65, 69, 59, 3, 9, 66, 66, 67, 67, 65, 0, 46, 0, 65, 70, 68, 1, 9, 69, 0, 0, 0, 72, 71, -1, 6, 73, 70, 74, 3, 75, 1, 76, 71, 77, 1, 78, 3, 0, 0, 0, 1, 79, -1, 0, 0, 52, 0, 62, 80, 72, 1, 9, 73, 0, 52, 0, 62, 81, 72, 1, 9, 74, 0, 52, 0, 62, 82, 72, 1, 9, 75, 0, 52, 0, 62, 83, 72, 1, 9, 76, 0, 52, 0, 62, 84, 72, 1, 9, 77, 0, 52, 0, 62, 85, 72, 1, 9, 78, 0, 52, 0, 62, 86, 72, 1, 9, 79, 0, 52, 0, 62, 87, 72, 1, 9, 80, 0, 52, 0, 62, 88, 72, 1, 9, 81, 0, 52, 0, 62, 89, 72, 1, 9, 82, 0, 52, 0, 62, 90, 72, 1, 9, 83, 0, 0, 0, 92, 91, 84, 0, 0, 0, 0, 93, 93, -1, 29, 5, 1, 6, 2, 7, 2, 8, 3, 94, 85, 95, 86, 96, 87, 97, 88, 98, 89, 99, 89, 100, 89, 101, 89, 102, 1, 103, 1, 104, 90, 105, 2, 106, 5, 107, 91, 108, 2, 109, 92, 110, 5, 111, 3, 112, 3, 113, 93, 114, 94, 115, 94, 116, 1, 117, 3, 118, 95, 0 </int_array>
<string> "conns" </string>
<int_array len="0"> </int_array>
</dictionary>
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 2fffbb823e..f43b43bd77 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -952,7 +952,11 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) {
Texture *texture = texture_owner.get( p_texture );
ERR_FAIL_COND(!texture);
- ERR_FAIL_COND(texture->render_target);
+ if (texture->render_target) {
+
+ p_flags&=VS::TEXTURE_FLAG_FILTER;//can change only filter
+ }
+
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
@@ -5180,6 +5184,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
+ bool stores_glow = !shadow && (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) && !p_alpha_pass;
bool prev_blend=false;
glDisable(GL_BLEND);
@@ -5200,7 +5205,6 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
if (!shadow) {
if (texscreen_used && !texscreen_copied && material->shader_cache && material->shader_cache->valid && material->shader_cache->has_texscreen) {
-
texscreen_copied=true;
_copy_to_texscreen();
@@ -5247,11 +5251,15 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
if (!*e->additive_ptr) {
additive=false;
- *e->additive_ptr=true;
+ *e->additive_ptr=true;
} else {
additive=true;
}
+ if (stores_glow)
+ material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,!additive);
+
+
bool desired_blend=false;
VS::MaterialBlendMode desired_blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
@@ -5894,7 +5902,7 @@ void RasterizerGLES2::end_scene() {
glDisable(GL_BLEND);
current_blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
- material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]);
+ //material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]);
opaque_render_list.sort_mat_light_type_flags();
_render_list_forward(&opaque_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting);
@@ -5950,12 +5958,15 @@ void RasterizerGLES2::end_scene() {
glBindFramebuffer(GL_FRAMEBUFFER, current_rt?current_rt->fbo:base_framebuffer);
+ Size2 size;
if (current_rt) {
glBindFramebuffer(GL_FRAMEBUFFER, current_rt->fbo);
glViewport( 0,0,viewport.width,viewport.height);
+ size=Size2(viewport.width,viewport.height);
} else {
glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
glViewport( viewport.x, window_size.height-(viewport.height+viewport.y), viewport.width,viewport.height );
+ size=Size2(viewport.width,viewport.height);
}
//time to copy!!!
@@ -5964,6 +5975,7 @@ void RasterizerGLES2::end_scene() {
copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW,current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]);
copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,current_env && current_env->fx_enabled[VS::ENV_FX_HDR]);
copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA,true);
+ copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,current_env && current_env->fx_enabled[VS::ENV_FX_FXAA]);
copy_shader.bind();
//copy_shader.set_uniform(CopyShaderGLES2::SOURCE,0);
@@ -5985,6 +5997,9 @@ void RasterizerGLES2::end_scene() {
}
+ if (current_env && current_env->fx_enabled[VS::ENV_FX_FXAA])
+ copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Size2(1.0/size.x,1.0/size.y));
+
if (current_env && current_env->fx_enabled[VS::ENV_FX_BCS]) {
@@ -6008,6 +6023,7 @@ void RasterizerGLES2::end_scene() {
copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW,false);
copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false);
copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA,false);
+ copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,false);
material_shader.set_conditional(MaterialShaderGLES2::USE_HDR,false);
diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl
index d4b0c31b7d..bea651bceb 100644
--- a/drivers/gles2/shaders/copy.glsl
+++ b/drivers/gles2/shaders/copy.glsl
@@ -110,6 +110,11 @@ uniform sampler2D source_vd_lum;
#endif
+//endif
+#elif defined(USE_FXAA)
+
+uniform vec2 pixel_size;
+
#endif
#ifdef USE_ENERGY
@@ -129,6 +134,55 @@ void main() {
vec4 color = texture2D( source, uv_interp );
#endif
+
+#ifdef USE_FXAA
+
+#define FXAA_REDUCE_MIN (1.0/ 128.0)
+#define FXAA_REDUCE_MUL (1.0 / 8.0)
+#define FXAA_SPAN_MAX 8.0
+
+ {
+ vec3 rgbNW = texture2D(source, uv_interp + vec2(-1.0, -1.0) * pixel_size).xyz;
+ vec3 rgbNE = texture2D(source, uv_interp + vec2(1.0, -1.0) * pixel_size).xyz;
+ vec3 rgbSW = texture2D(source, uv_interp + vec2(-1.0, 1.0) * pixel_size).xyz;
+ vec3 rgbSE = texture2D(source, uv_interp + vec2(1.0, 1.0) * pixel_size).xyz;
+ vec3 rgbM = color.rgb;
+ vec3 luma = vec3(0.299, 0.587, 0.114);
+ float lumaNW = dot(rgbNW, luma);
+ float lumaNE = dot(rgbNE, luma);
+ float lumaSW = dot(rgbSW, luma);
+ float lumaSE = dot(rgbSE, luma);
+ float lumaM = dot(rgbM, luma);
+ float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
+ float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
+
+ vec2 dir;
+ dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
+ dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
+
+ float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
+ (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
+
+ float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
+ dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
+ max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
+ dir * rcpDirMin)) * pixel_size;
+
+ vec3 rgbA = 0.5 * (
+ texture2D(source, uv_interp + dir * (1.0 / 3.0 - 0.5)).xyz +
+ texture2D(source, uv_interp + dir * (2.0 / 3.0 - 0.5)).xyz);
+ vec3 rgbB = rgbA * 0.5 + 0.25 * (
+ texture2D(source, uv_interp + dir * -0.5).xyz +
+ texture2D(source, uv_interp + dir * 0.5).xyz);
+
+ float lumaB = dot(rgbB, luma);
+ if ((lumaB < lumaMin) || (lumaB > lumaMax))
+ color.rgb = rgbA;
+ else
+ color.rgb = rgbB;
+ }
+
+#endif
//color.rg=uv_interp;
#ifdef USE_BCS
@@ -195,7 +249,16 @@ void main() {
vec4 glow = texture2D( glow_source, uv2_interp );
+#if 1
+//ifdef USE_GLOW_SCREEN
+
+ color.rgb = clamp((color.rgb + glow.rgb) - (color.rgb * glow.rgb), 0.0, 1.0);
+
+#else
color.rgb+=glow.rgb;
+#endif
+
+
#endif
diff --git a/drivers/openssl/stream_peer_openssl.cpp b/drivers/openssl/stream_peer_openssl.cpp
index 0151ced3b8..ef07f11334 100644
--- a/drivers/openssl/stream_peer_openssl.cpp
+++ b/drivers/openssl/stream_peer_openssl.cpp
@@ -362,6 +362,7 @@ Error StreamPeerOpenSSL::connect(Ref<StreamPeer> p_base, bool p_validate_certs,
print_line("CONNECTION RESULT: "+itos(result));
if (result<1) {
+ ERR_print_errors_fp(stdout);
_print_error(result);
}
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index 65b10399f8..c6183aadc4 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -2153,6 +2153,7 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
"and",
"or",
"export",
+ "assert",
0};
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 3a101515da..5bc433e85f 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -676,7 +676,7 @@ String OS_Android::get_unique_ID() const {
return OS::get_unique_ID();
}
-Error OS_Android::native_video_play(String p_path) {
+Error OS_Android::native_video_play(String p_path, float p_volume) {
if (video_play_func)
video_play_func(p_path);
return OK;
@@ -719,6 +719,11 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFu
get_locale_func=p_get_locale_func;
get_model_func=p_get_model_func;
get_unique_id_func=p_get_unique_id;
+
+ video_play_func = p_video_play_func;
+ video_is_playing_func = p_video_is_playing_func;
+ video_pause_func = p_video_pause_func;
+ video_stop_func = p_video_stop_func;
show_virtual_keyboard_func = p_show_vk;
hide_virtual_keyboard_func = p_hide_vk;
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 76139c8a2d..e6d0f7eded 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -208,7 +208,7 @@ public:
void process_event(InputEvent p_event);
void init_video_mode(int p_video_width,int p_video_height);
- virtual Error native_video_play(String p_path);
+ virtual Error native_video_play(String p_path, float p_volume);
virtual bool native_video_is_playing();
virtual void native_video_pause();
virtual void native_video_stop();
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index 56cb73ba7b..c5ac5d9263 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -165,6 +165,7 @@ static int frame_count = 0;
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
printf("****************** did receive memory warning!\n");
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_MEMORY_WARNING);
};
- (void)applicationDidFinishLaunching:(UIApplication*)application {
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index 402c755094..c482c36a30 100755
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -32,6 +32,7 @@
#include "os_iphone.h"
#include "core/os/keyboard.h"
#include "core/globals.h"
+#include "servers/audio_server.h"
#import "gl_view.h"
@@ -48,6 +49,9 @@ int gl_view_base_fb;
static String keyboard_text;
static GLView* _instance = NULL;
+static bool video_found_error = false;
+static float video_previous_volume = 0.0f;
+
void _show_keyboard(String p_existing) {
keyboard_text = p_existing;
printf("instance on show is %p\n", _instance);
@@ -60,8 +64,13 @@ void _hide_keyboard() {
keyboard_text = "";
};
-bool _play_video(String p_path) {
+bool _play_video(String p_path, float p_volume) {
+ float player_volume = p_volume * AudioServer::get_singleton()->get_singleton()->get_stream_global_volume_scale();
+ video_previous_volume = [[MPMusicPlayerController applicationMusicPlayer] volume];
+
+ [[MPMusicPlayerController applicationMusicPlayer] setVolume: player_volume];
+
p_path = Globals::get_singleton()->globalize_path(p_path);
NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease];
@@ -87,6 +96,8 @@ bool _play_video(String p_path) {
bool _is_video_playing() {
//NSInteger playback_state = _instance.moviePlayerController.playbackState;
+ if (video_found_error)
+ return false;
return (_instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying);
}
@@ -97,6 +108,7 @@ void _pause_video() {
void _stop_video() {
[_instance.moviePlayerController stop];
[_instance.moviePlayerController.view removeFromSuperview];
+ [[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume];
}
@implementation GLView
@@ -506,13 +518,37 @@ static void clear_touches() {
}
- (void)moviePlayBackDidFinish:(NSNotification*)notification {
+
+
+ NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
+ switch ([reason intValue]) {
+ case MPMovieFinishReasonPlaybackEnded:
+ //NSLog(@"Playback Ended");
+ break;
+ case MPMovieFinishReasonPlaybackError:
+ //NSLog(@"Playback Error");
+ video_found_error = true;
+ break;
+ case MPMovieFinishReasonUserExited:
+ //NSLog(@"User Exited");
+ video_found_error = true;
+ break;
+ default:
+ //NSLog(@"Unsupported reason!");
+ break;
+ }
+
MPMoviePlayerController *player = [notification object];
+
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
+ [_instance.moviePlayerController stop];
[_instance.moviePlayerController.view removeFromSuperview];
+
+ [[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume];
}
@end
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index 756e8b575e..2ef732183b 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -485,13 +485,13 @@ String OSIPhone::get_locale() const {
return locale_code;
}
-extern bool _play_video(String p_path);
+extern bool _play_video(String p_path, float p_volume);
extern bool _is_video_playing();
extern void _pause_video();
extern void _stop_video();
-Error OSIPhone::native_video_play(String p_path) {
- if ( _play_video(p_path) )
+Error OSIPhone::native_video_play(String p_path, float p_volume) {
+ if ( _play_video(p_path, p_volume) )
return OK;
return FAILED;
}
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 643bf2b5e3..14b46816e9 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -184,7 +184,7 @@ public:
void set_unique_ID(String p_ID);
String get_unique_ID() const;
- virtual Error native_video_play(String p_path);
+ virtual Error native_video_play(String p_path, float p_volume);
virtual bool native_video_is_playing() const;
virtual void native_video_pause();
virtual void native_video_stop();
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index a2bee43e58..85adfbbbde 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -224,6 +224,30 @@ Rect2 Node2D::get_item_rect() const {
return Rect2(Point2(-32,-32),Size2(64,64));
}
+void Node2D::rotate(float p_degrees) {
+
+ set_rot( get_rot() + p_degrees);
+}
+
+void Node2D::move_x(float p_delta,bool p_scaled){
+
+ Matrix32 t = get_transform();
+ Vector2 m = t[0];
+ if (!p_scaled)
+ m.normalize();
+ set_pos(t[2]+m*p_delta);
+}
+
+void Node2D::move_y(float p_delta,bool p_scaled){
+
+ Matrix32 t = get_transform();
+ Vector2 m = t[1];
+ if (!p_scaled)
+ m.normalize();
+ set_pos(t[2]+m*p_delta);
+}
+
+
Point2 Node2D::get_global_pos() const {
return get_global_transform().get_origin();
@@ -268,6 +292,10 @@ void Node2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_rot"),&Node2D::get_rot);
ObjectTypeDB::bind_method(_MD("get_scale"),&Node2D::get_scale);
+ ObjectTypeDB::bind_method(_MD("rotate","degrees"),&Node2D::rotate);
+ ObjectTypeDB::bind_method(_MD("move_local_x","delta","scaled"),&Node2D::move_x,DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("move_local_y","delta","scaled"),&Node2D::move_y,DEFVAL(false));
+
ObjectTypeDB::bind_method(_MD("get_global_pos"),&Node2D::get_global_pos);
ObjectTypeDB::bind_method(_MD("set_transform","xform"),&Node2D::set_transform);
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index 8da441dc63..8e1f22c235 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -70,6 +70,10 @@ public:
void set_rot(float p_angle);
void set_scale(const Size2& p_scale);
+ void rotate(float p_degrees);
+ void move_x(float p_delta,bool p_scaled=false);
+ void move_y(float p_delta,bool p_scaled=false);
+
Point2 get_pos() const;
float get_rot() const;
Size2 get_scale() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index a1e7195b0a..ecd147afde 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -43,9 +43,27 @@ void PhysicsBody2D::_notification(int p_what) {
*/
}
-PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) {
+void PhysicsBody2D::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask);
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+}
+
+void PhysicsBody2D::set_layer_mask(uint32_t p_mask) {
+
+ mask=p_mask;
+ Physics2DServer::get_singleton()->body_set_layer_mask(get_rid(),p_mask);
+}
+
+uint32_t PhysicsBody2D::get_layer_mask() const {
+ return mask;
+}
+
+PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) {
+ mask=1;
}
@@ -789,7 +807,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
for(int i=0;i<get_shape_count();i++) {
- if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,0,mask))
+ if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,get_layer_mask(),mask))
collided=true;
}
@@ -834,7 +852,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
float lsafe,lunsafe;
- bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,0,mask);
+ bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,get_layer_mask(),mask);
//print_line("shape: "+itos(i)+" travel:"+rtos(ltravel));
if (!valid) {
safe=0;
@@ -865,7 +883,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
Matrix32 ugt = get_global_transform();
ugt.elements[2]+=p_motion*unsafe;
Physics2DDirectSpaceState::ShapeRestInfo rest_info;
- bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,0,mask);
+ bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,get_layer_mask(),mask);
if (!c2) {
//should not happen, but floating point precision is so weird..
colliding=false;
@@ -927,7 +945,7 @@ bool KinematicBody2D::can_move_to(const Vector2& p_position, bool p_discrete) {
for(int i=0;i<get_shape_count();i++) {
- bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),motion,0,NULL,0,exclude,0,mask);
+ bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),motion,0,NULL,0,exclude,get_layer_mask(),mask);
if (col)
return false;
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index e7b65b1ef3..1319d2e4f0 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -38,12 +38,18 @@ class PhysicsBody2D : public CollisionObject2D {
OBJ_TYPE(PhysicsBody2D,CollisionObject2D);
+ uint32_t mask;
protected:
void _notification(int p_what);
PhysicsBody2D(Physics2DServer::BodyMode p_mode);
+
+ static void _bind_methods();
public:
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
PhysicsBody2D();
};
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 540c825485..8479338521 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -43,6 +43,16 @@ Vector2 RayCast2D::get_cast_to() const{
return cast_to;
}
+void RayCast2D::set_layer_mask(uint32_t p_mask) {
+
+ layer_mask=p_mask;
+}
+
+uint32_t RayCast2D::get_layer_mask() const {
+
+ return layer_mask;
+}
+
bool RayCast2D::is_colliding() const{
return collided;
@@ -152,7 +162,7 @@ void RayCast2D::_notification(int p_what) {
Physics2DDirectSpaceState::RayResult rr;
- if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude)) {
+ if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask)) {
collided=true;
against=rr.collider_id;
@@ -228,8 +238,12 @@ void RayCast2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("clear_exceptions"),&RayCast2D::clear_exceptions);
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast2D::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast2D::get_layer_mask);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
}
RayCast2D::RayCast2D() {
@@ -238,5 +252,6 @@ RayCast2D::RayCast2D() {
against=0;
collided=false;
against_shape=0;
+ layer_mask=1;
cast_to=Vector2(0,50);
}
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index 32b95fbefe..b27fc4bf3d 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -43,6 +43,7 @@ class RayCast2D : public Node2D {
Vector2 collision_point;
Vector2 collision_normal;
Set<RID> exclude;
+ uint32_t layer_mask;
Vector2 cast_to;
@@ -58,6 +59,9 @@ public:
void set_cast_to(const Vector2& p_point);
Vector2 get_cast_to() const;
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
bool is_colliding() const;
Object *get_collider() const;
int get_collider_shape() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index c8711f10ac..6fe8b8c4c2 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -315,6 +315,7 @@ Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const
VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() );
VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform );
q.static_body=Physics2DServer::get_singleton()->body_create(Physics2DServer::BODY_MODE_STATIC);
+ Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer);
if (is_inside_scene()) {
xform = get_global_transform() * xform;
RID space = get_world_2d()->get_space();
@@ -545,6 +546,22 @@ Rect2 TileMap::get_item_rect() const {
return rect_cache;
}
+void TileMap::set_collision_layer_mask(uint32_t p_layer) {
+
+ collision_layer=p_layer;
+ for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) {
+
+ Quadrant &q=E->get();
+ Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer);
+ }
+}
+
+uint32_t TileMap::get_collision_layer_mask() const {
+
+ return collision_layer;
+}
+
+
void TileMap::_bind_methods() {
@@ -564,6 +581,8 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_center_y","enable"),&TileMap::set_center_y);
ObjectTypeDB::bind_method(_MD("get_center_y"),&TileMap::get_center_y);
+ ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask);
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell);
@@ -583,6 +602,7 @@ void TileMap::_bind_methods() {
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::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,"collision_layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask"));
ADD_SIGNAL(MethodInfo("settings_changed"));
@@ -599,6 +619,7 @@ TileMap::TileMap() {
cell_size=64;
center_x=false;
center_y=false;
+ collision_layer=1;
fp_adjust=0.01;
fp_adjust=0.01;
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index a2414382c6..9265a7b55e 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -98,6 +98,7 @@ class TileMap : public Node2D {
Rect2 rect_cache;
bool rect_cache_dirty;
float fp_adjust;
+ uint32_t collision_layer;
Map<PosKey,Quadrant>::Element *_create_quadrant(const PosKey& p_qk);
@@ -145,6 +146,9 @@ public:
Rect2 get_item_rect() const;
+ void set_collision_layer_mask(uint32_t p_layer);
+ uint32_t get_collision_layer_mask() const;
+
void clear();
TileMap();
diff --git a/scene/3d/baked_light.cpp b/scene/3d/baked_light.cpp
new file mode 100644
index 0000000000..55832b7c18
--- /dev/null
+++ b/scene/3d/baked_light.cpp
@@ -0,0 +1,7 @@
+#include "baked_light.h"
+#include "mesh_instance.h"
+
+BakedLight::BakedLight() {
+
+
+}
diff --git a/scene/3d/baked_light.h b/scene/3d/baked_light.h
new file mode 100644
index 0000000000..a6f997afe9
--- /dev/null
+++ b/scene/3d/baked_light.h
@@ -0,0 +1,15 @@
+#ifndef BAKED_LIGHT_H
+#define BAKED_LIGHT_H
+
+#include "scene/3d/spatial.h"
+class BakedLightBaker;
+
+
+class BakedLight : public Spatial {
+ OBJ_TYPE(BakedLight,Spatial);
+
+public:
+ BakedLight();
+};
+
+#endif // BAKED_LIGHT_H
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 0733a9196e..2a1a5972a9 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -632,6 +632,16 @@ bool RigidBody::is_contact_monitor_enabled() const {
return contact_monitor!=NULL;
}
+void RigidBody::set_axis_lock(AxisLock p_lock) {
+
+ axis_lock=p_lock;
+ PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(),PhysicsServer::BodyAxisLock(axis_lock));
+}
+
+RigidBody::AxisLock RigidBody::get_axis_lock() const {
+
+ return axis_lock;
+}
void RigidBody::_bind_methods() {
@@ -682,6 +692,9 @@ void RigidBody::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_body_enter_scene"),&RigidBody::_body_enter_scene);
ObjectTypeDB::bind_method(_MD("_body_exit_scene"),&RigidBody::_body_exit_scene);
+ ObjectTypeDB::bind_method(_MD("set_axis_lock","axis_lock"),&RigidBody::set_axis_lock);
+ ObjectTypeDB::bind_method(_MD("get_axis_lock"),&RigidBody::get_axis_lock);
+
BIND_VMETHOD(MethodInfo("_integrate_forces",PropertyInfo(Variant::OBJECT,"state:PhysicsDirectBodyState")));
ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Rigid,Static,Character,Kinematic"),_SCS("set_mode"),_SCS("get_mode"));
@@ -695,6 +708,7 @@ void RigidBody::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"contact_monitor"),_SCS("set_contact_monitor"),_SCS("is_contact_monitor_enabled"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"active"),_SCS("set_active"),_SCS("is_active"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"can_sleep"),_SCS("set_can_sleep"),_SCS("is_able_to_sleep"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"axis_lock",PROPERTY_HINT_ENUM,"Disabled,Lock X,Lock Y,Lock Z"),_SCS("set_axis_lock"),_SCS("get_axis_lock"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"velocity/linear"),_SCS("set_linear_velocity"),_SCS("get_linear_velocity"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"velocity/angular"),_SCS("set_angular_velocity"),_SCS("get_angular_velocity"));
@@ -727,6 +741,8 @@ RigidBody::RigidBody() : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
contact_monitor=NULL;
can_sleep=true;
+ axis_lock = AXIS_LOCK_DISABLED;
+
PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(),this,"_direct_state_changed");
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index a5faa9857b..6695ee719a 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -94,6 +94,14 @@ public:
MODE_CHARACTER,
MODE_KINEMATIC,
};
+
+ enum AxisLock {
+ AXIS_LOCK_DISABLED,
+ AXIS_LOCK_X,
+ AXIS_LOCK_Y,
+ AXIS_LOCK_Z,
+ };
+
private:
bool can_sleep;
@@ -109,6 +117,8 @@ private:
bool active;
bool ccd;
+ AxisLock axis_lock;
+
int max_contacts_reported;
@@ -208,6 +218,10 @@ public:
void set_use_continuous_collision_detection(bool p_enable);
bool is_using_continuous_collision_detection() const;
+ void set_axis_lock(AxisLock p_lock);
+ AxisLock get_axis_lock() const;
+
+
void apply_impulse(const Vector3& p_pos, const Vector3& p_impulse);
RigidBody();
@@ -216,4 +230,5 @@ public:
};
VARIANT_ENUM_CAST(RigidBody::Mode);
+VARIANT_ENUM_CAST(RigidBody::AxisLock);
#endif // PHYSICS_BODY__H
diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h
index 4e652912c6..afb9ed70f8 100644
--- a/scene/3d/visual_instance.h
+++ b/scene/3d/visual_instance.h
@@ -91,6 +91,7 @@ public:
FLAG_BILLBOARD_FIX_Y=VS::INSTANCE_FLAG_BILLBOARD_FIX_Y,
FLAG_DEPH_SCALE=VS::INSTANCE_FLAG_DEPH_SCALE,
FLAG_VISIBLE_IN_ALL_ROOMS=VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
+ FLAG_USE_BAKED_LIGHT_VOLUME=VS::INSTANCE_FLAG_USE_BAKED_LIGHT_VOLUME,
FLAG_MAX=VS::INSTANCE_FLAG_MAX,
};
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index c659447c23..15d3dccb71 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -907,8 +907,8 @@ void AnimationPlayer::play(const StringName& p_name, float p_custom_blend, float
}
}
- c.current.pos=p_from_end ? c.current.from->animation->get_length() : 0;
c.current.from=&animation_set[name];
+ c.current.pos=p_from_end ? c.current.from->animation->get_length() : 0;
c.current.speed_scale=p_custom_scale;
c.assigned=p_name;
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 5ac278a38e..241d66fce4 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1512,6 +1512,10 @@ void RichTextLabel::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_selection_enabled","enabled"),&RichTextLabel::set_selection_enabled);
ObjectTypeDB::bind_method(_MD("is_selection_enabled"),&RichTextLabel::is_selection_enabled);
+ ObjectTypeDB::bind_method(_MD("parse_bbcode", "bbcode"),&RichTextLabel::parse_bbcode);
+ ObjectTypeDB::bind_method(_MD("append_bbcode", "bbcode"),&RichTextLabel::append_bbcode);
+
+
ADD_SIGNAL( MethodInfo("meta_clicked",PropertyInfo(Variant::NIL,"meta")));
BIND_CONSTANT( ALIGN_LEFT );
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 0bbc2dc695..91769bbb82 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -728,6 +728,7 @@ void Viewport::set_as_render_target(bool p_enable){
render_target_texture_rid=RID();
}
+ render_target_texture->set_flags(render_target_texture->flags);
render_target_texture->emit_changed();
}
@@ -773,6 +774,18 @@ bool Viewport::get_render_target_vflip() const{
}
+void Viewport::set_render_target_filter(bool p_enable) {
+
+ render_target_texture->set_flags(p_enable?int(Texture::FLAG_FILTER):int(0));
+
+}
+
+bool Viewport::get_render_target_filter() const{
+
+ return (render_target_texture->get_flags()&Texture::FLAG_FILTER)!=0;
+}
+
+
Matrix32 Viewport::_get_input_pre_xform() const {
Matrix32 pre_xf;
@@ -990,6 +1003,9 @@ void Viewport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip);
ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip);
+ ObjectTypeDB::bind_method(_MD("set_render_target_filter","enable"), &Viewport::set_render_target_filter);
+ ObjectTypeDB::bind_method(_MD("get_render_target_filter"), &Viewport::get_render_target_filter);
+
ObjectTypeDB::bind_method(_MD("set_render_target_update_mode","mode"), &Viewport::set_render_target_update_mode);
ObjectTypeDB::bind_method(_MD("get_render_target_update_mode"), &Viewport::get_render_target_update_mode);
@@ -1020,6 +1036,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_render_target_vflip"), _SCS("get_render_target_vflip") );
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/filter"), _SCS("set_render_target_filter"), _SCS("get_render_target_filter") );
ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_2d"), _SCS("set_as_audio_listener_2d"), _SCS("is_audio_listener_2d") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_3d"), _SCS("set_as_audio_listener"), _SCS("is_audio_listener") );
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index cc7f93cfa3..d54b489843 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -113,6 +113,7 @@ friend class RenderTargetTexture;
bool transparent_bg;
bool render_target_vflip;
+ bool render_target_filter;
void _update_rect();
@@ -210,6 +211,9 @@ public:
void set_render_target_vflip(bool p_enable);
bool get_render_target_vflip() const;
+ void set_render_target_filter(bool p_enable);
+ bool get_render_target_filter() const;
+
void set_render_target_update_mode(RenderTargetUpdateMode p_mode);
RenderTargetUpdateMode get_render_target_update_mode() const;
Ref<RenderTargetTexture> get_render_target_texture() const;
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 8fd39b0d74..b30ad2d71f 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -187,6 +187,7 @@
#include "scene/3d/area.h"
#include "scene/3d/physics_joint.h"
#include "scene/3d/multimesh_instance.h"
+#include "scene/3d/baked_light.h"
#include "scene/3d/ray_cast.h"
#include "scene/3d/spatial_sample_player.h"
#include "scene/3d/spatial_stream_player.h"
@@ -401,7 +402,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<PathFollow>();
ObjectTypeDB::register_type<VisibilityNotifier>();
ObjectTypeDB::register_type<VisibilityEnabler>();
-
+ ObjectTypeDB::register_type<BakedLight>();
ObjectTypeDB::register_type<WorldEnvironment>();
//scenariofx
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 3e12c7a5b5..0c55d22dbe 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -101,6 +101,8 @@ void Environment::_bind_methods() {
ObjectTypeDB::bind_method(_MD("fx_set_param","param","value"),&Environment::fx_set_param);
ObjectTypeDB::bind_method(_MD("fx_get_param","param"),&Environment::fx_get_param);
+ ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"fxaa/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_FXAA);
+
ADD_PROPERTY( PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Keep,Default Color,Color,Texture,Cubemap,Texture RGBE,Cubemap RGBE"),_SCS("set_background"),_SCS("get_background"));
ADD_PROPERTYI( PropertyInfo(Variant::COLOR,"background/color"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_COLOR);
ADD_PROPERTYI( PropertyInfo(Variant::OBJECT,"background/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_TEXTURE);
@@ -181,6 +183,7 @@ void Environment::_bind_methods() {
BIND_CONSTANT( BG_PARAM_MAX );
+ BIND_CONSTANT( FX_FXAA );
BIND_CONSTANT( FX_GLOW );
BIND_CONSTANT( FX_DOF_BLUR );
BIND_CONSTANT( FX_HDR );
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index c94c81b694..b90a043634 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -60,6 +60,7 @@ public:
};
enum Fx {
+ FX_FXAA=VS::ENV_FX_FXAA,
FX_GLOW=VS::ENV_FX_GLOW,
FX_DOF_BLUR=VS::ENV_FX_DOF_BLUR,
FX_HDR=VS::ENV_FX_HDR,
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 6d0a1cf76b..c6e492fcb3 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -92,10 +92,17 @@ bool Mesh::_set(const StringName& p_name, const Variant& p_value) {
return true;
}
- if (sname.begins_with("materials/")) {
-
- int idx=sname.get_slice("/",1).to_int()-1;
- surface_set_material(idx,p_value);
+ if (sname.begins_with("surface_")) {
+
+ int sl=sname.find("/");
+ if (sl==-1)
+ return false;
+ int idx=sname.substr(8,sl-8).to_int()-1;
+ String what = sname.get_slice("/",1);
+ if (what=="material")
+ surface_set_material(idx,p_value);
+ else if (what=="name")
+ surface_set_name(idx,p_value);
return true;
}
@@ -166,10 +173,17 @@ bool Mesh::_get(const StringName& p_name,Variant &r_ret) const {
r_ret = get_morph_target_mode();
return true;
- } else if (sname.begins_with("materials/")) {
-
- int idx=sname.get_slice("/",1).to_int()-1;
- r_ret=surface_get_material(idx);
+ } else if (sname.begins_with("surface_")) {
+
+ int sl=sname.find("/");
+ if (sl==-1)
+ return false;
+ int idx=sname.substr(8,sl-8).to_int()-1;
+ String what = sname.get_slice("/",1);
+ if (what=="material")
+ r_ret=surface_get_material(idx);
+ else if (what=="name")
+ r_ret=surface_get_name(idx);
return true;
} else if (sname=="custom_aabb/custom_aabb") {
@@ -210,7 +224,8 @@ void Mesh::_get_property_list( List<PropertyInfo> *p_list) const {
for (int i=0;i<surfaces.size();i++) {
p_list->push_back( PropertyInfo( Variant::DICTIONARY,"surfaces/"+itos(i), PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR ) );
- p_list->push_back( PropertyInfo( Variant::OBJECT,"materials/"+itos(i+1), PROPERTY_HINT_RESOURCE_TYPE,"Material",PROPERTY_USAGE_EDITOR ) );
+ p_list->push_back( PropertyInfo( Variant::STRING,"surface_"+itos(i+1)+"/name", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR ) );
+ p_list->push_back( PropertyInfo( Variant::OBJECT,"surface_"+itos(i+1)+"/material", PROPERTY_HINT_RESOURCE_TYPE,"Material",PROPERTY_USAGE_EDITOR ) );
}
p_list->push_back( PropertyInfo( Variant::_AABB,"custom_aabb/custom_aabb" ) );
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index d0c159e9f0..2856101674 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -32,57 +32,56 @@
#define EQ_VERTEX_DIST 0.00001
+bool SurfaceTool::Vertex::operator==(const Vertex& p_b) const {
-bool SurfaceTool::compare(const Vertex& p_a,const Vertex& p_b) const {
- if (p_a.vertex.distance_to(p_b.vertex)>EQ_VERTEX_DIST)
+ if (vertex!=p_b.vertex)
return false;
- if (format&Mesh::ARRAY_FORMAT_TEX_UV) {
+ if (uv!=p_b.uv)
+ return false;
- if (p_a.uv.distance_to(p_b.uv)>EQ_VERTEX_DIST)
- return false;
- }
+ if (uv2!=p_b.uv2)
+ return false;
- if (format&Mesh::ARRAY_FORMAT_TEX_UV2) {
+ if (normal!=p_b.normal)
+ return false;
- if (p_a.uv2.distance_to(p_b.uv2)>EQ_VERTEX_DIST)
- return false;
- }
+ if (binormal!=p_b.binormal)
+ return false;
- if (format&Mesh::ARRAY_FORMAT_NORMAL) {
- if (p_a.normal.distance_to(p_b.normal)>EQ_VERTEX_DIST)
- return false;
- }
+ if (color!=p_b.color)
+ return false;
- if (format&Mesh::ARRAY_FORMAT_TANGENT) {
- if (p_a.binormal.distance_to(p_b.binormal)>EQ_VERTEX_DIST)
- return false;
- if (p_a.tangent.distance_to(p_b.tangent)>EQ_VERTEX_DIST)
+ if (bones.size()!=p_b.bones.size())
+ return false;
+
+ for(int i=0;i<bones.size();i++) {
+ if (bones[i]!=p_b.bones[i])
return false;
}
- if (format&Mesh::ARRAY_FORMAT_COLOR) {
- if (p_a.color!=p_b.color)
+ for(int i=0;i<weights.size();i++) {
+ if (weights[i]!=p_b.weights[i])
return false;
}
- if (format&Mesh::ARRAY_FORMAT_BONES) {
- for(int i=0;i<4;i++) {
- if (Math::abs(p_a.bones[i]-p_b.bones[i])>CMP_EPSILON)
- return false;
- }
- }
+ return true;
+}
- if (format&Mesh::ARRAY_FORMAT_WEIGHTS) {
- for(int i=0;i<4;i++) {
- if (Math::abs(p_a.weights[i]-p_b.weights[i])>CMP_EPSILON)
- return false;
- }
- }
+uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
- return true;
+ uint32_t h = hash_djb2_buffer((const uint8_t*)&p_vtx.vertex,sizeof(real_t)*3);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.normal,sizeof(real_t)*3,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.binormal,sizeof(real_t)*3,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.tangent,sizeof(real_t)*3,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.uv,sizeof(real_t)*2,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.uv2,sizeof(real_t)*2,h);
+ h = hash_djb2_buffer((const uint8_t*)&p_vtx.color,sizeof(real_t)*4,h);
+ h = hash_djb2_buffer((const uint8_t*)p_vtx.bones.ptr(),p_vtx.bones.size()*sizeof(int),h);
+ h = hash_djb2_buffer((const uint8_t*)p_vtx.weights.ptr(),p_vtx.weights.size()*sizeof(float),h);
+ return h;
}
void SurfaceTool::begin(Mesh::PrimitiveType p_primitive) {
@@ -186,6 +185,17 @@ void SurfaceTool::add_weights( const Vector<float>& p_weights) {
}
+void SurfaceTool::add_smooth_group(bool p_smooth) {
+
+ ERR_FAIL_COND(!begun);
+ if (index_array.size()) {
+ smooth_groups[index_array.size()]=p_smooth;
+ } else {
+
+ smooth_groups[vertex_array.size()]=p_smooth;
+ }
+}
+
void SurfaceTool::add_index( int p_index) {
@@ -377,79 +387,53 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) {
void SurfaceTool::index() {
-#if 0
- printf("indexing..\n");
- ERR_FAIL_COND( format & Surface::ARRAY_FORMAT_INDEX ); // already indexed
-
- index_array.clear();
- DVector< Vertex > indexed_vertex_array;
+ if (index_array.size())
+ return; //already indexed
- int vertex_array_len = vertex_array.size();
- vertex_array.read_lock();
- const Vertex*vertex_array_ptr = vertex_array.read();
- for (int i=0;i<vertex_array_len;i++) {
+ HashMap<Vertex,int,VertexHasher> indices;
+ List<Vertex> new_vertices;
- int index_pos=-1;
+ for(List< Vertex >::Element *E=vertex_array.front();E;E=E->next()) {
- int indexed_vertex_array_len=indexed_vertex_array.size();
-
- if (indexed_vertex_array_len) {
-
- indexed_vertex_array.read_lock();
- const Vertex* indexed_vertex_array_ptr=indexed_vertex_array.read();
-
- for (int j=0;j<indexed_vertex_array_len;j++) {
-
- if (vertex_array_ptr[i].same_as(indexed_vertex_array_ptr[j])) {
-
- index_pos=j;
- break;
- }
- }
-
- indexed_vertex_array.read_unlock();
- }
-
- if (index_pos==-1) {
-
- index_pos=indexed_vertex_array.size();
- indexed_vertex_array.push_back(vertex_array_ptr[i]);
+ int *idxptr=indices.getptr(E->get());
+ int idx;
+ if (!idxptr) {
+ idx=indices.size();
+ new_vertices.push_back(E->get());
+ indices[E->get()]=idx;
} else {
-
- indexed_vertex_array.write_lock();
- indexed_vertex_array.write()[index_pos].normal+=vertex_array_ptr[i].normal;
- indexed_vertex_array.write()[index_pos].binormal+=vertex_array_ptr[i].binormal;
- indexed_vertex_array.write()[index_pos].tangent+=vertex_array_ptr[i].tangent;
- indexed_vertex_array.write_unlock();
+ idx=*idxptr;
}
- index_array.push_back(index_pos);
- }
-
- int idxvertsize=indexed_vertex_array.size();
- indexed_vertex_array.write_lock();
- Vertex* idxvert=indexed_vertex_array.write();
- for (int i=0;i<idxvertsize;i++) {
+ index_array.push_back(idx);
- idxvert[i].normal.normalize();
- idxvert[i].tangent.normalize();
- idxvert[i].binormal.normalize();
}
- indexed_vertex_array.write_unlock();
- vertex_array.read_unlock();
-
- format|=Surface::ARRAY_FORMAT_INDEX;
- vertex_array=indexed_vertex_array;
+ vertex_array.clear();
+ vertex_array=new_vertices;
- printf("indexing.. end\n");
-#endif
+ format|=Mesh::ARRAY_FORMAT_INDEX;
}
void SurfaceTool::deindex() {
+ if (index_array.size()==0)
+ return; //nothing to deindex
+ Vector< Vertex > varr;
+ varr.resize(vertex_array.size());
+ int idx=0;
+ for (List< Vertex >::Element *E=vertex_array.front();E;E=E->next()) {
+ varr[idx++]=E->get();
+ }
+ vertex_array.clear();
+ for (List<int>::Element *E=index_array.front();E;E=E->next()) {
+
+ ERR_FAIL_INDEX(E->get(),varr.size());
+ vertex_array.push_back(varr[E->get()]);
+ }
+ format&=~Mesh::ARRAY_FORMAT_INDEX;
}
@@ -631,80 +615,250 @@ void SurfaceTool::append_from(const Ref<Mesh>& p_existing, int p_surface,const T
void SurfaceTool::generate_tangents() {
ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_TEX_UV));
+ ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_NORMAL));
-#if 0
- int len=vertex_array.size();
- vertex_array.write_lock();
- Vertex *vertexptr=vertex_array.write();
-
- for (int i=0;i<len/3;i++) {
+ if (index_array.size()) {
+ Vector<List<Vertex>::Element*> vtx;
+ vtx.resize(vertex_array.size());
+ int idx=0;
+ for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) {
+ vtx[idx++]=E;
+ E->get().binormal=Vector3();
+ E->get().tangent=Vector3();
+ }
- Vector3 v1 = vertexptr[i*3+0].vertex;
- Vector3 v2 = vertexptr[i*3+1].vertex;
- Vector3 v3 = vertexptr[i*3+2].vertex;
+ for (List<int>::Element *E=index_array.front();E;) {
+
+ int i[3];
+ i[0]=E->get();
+ E=E->next();
+ ERR_FAIL_COND(!E);
+ i[1]=E->get();
+ E=E->next();
+ ERR_FAIL_COND(!E);
+ i[2]=E->get();
+ E=E->next();
+ ERR_FAIL_COND(!E);
+
+
+ Vector3 v1 = vtx[ i[0] ]->get().vertex;
+ Vector3 v2 = vtx[ i[1] ]->get().vertex;
+ Vector3 v3 = vtx[ i[2] ]->get().vertex;
+
+ Vector2 w1 = vtx[ i[0] ]->get().uv;
+ Vector2 w2 = vtx[ i[1] ]->get().uv;
+ Vector2 w3 = vtx[ i[2] ]->get().uv;
+
+
+ float x1 = v2.x - v1.x;
+ float x2 = v3.x - v1.x;
+ float y1 = v2.y - v1.y;
+ float y2 = v3.y - v1.y;
+ float z1 = v2.z - v1.z;
+ float z2 = v3.z - v1.z;
+
+ float s1 = w2.x - w1.x;
+ float s2 = w3.x - w1.x;
+ float t1 = w2.y - w1.y;
+ float t2 = w3.y - w1.y;
+
+ float r = (s1 * t2 - s2 * t1);
+
+ Vector3 binormal,tangent;
+
+ if (r==0) {
+ binormal=Vector3(0,0,0);
+ tangent=Vector3(0,0,0);
+ } else {
+ tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
+ binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
+ }
- Vector3 w1 = vertexptr[i*3+0].uv[0];
- Vector3 w2 = vertexptr[i*3+1].uv[0];
- Vector3 w3 = vertexptr[i*3+2].uv[0];
+ tangent.normalize();
+ binormal.normalize();
+ Vector3 normal=Plane( v1, v2, v3 ).normal;
+ Vector3 tangentp = tangent - normal * normal.dot( tangent );
+ Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal));
- float x1 = v2.x - v1.x;
- float x2 = v3.x - v1.x;
- float y1 = v2.y - v1.y;
- float y2 = v3.y - v1.y;
- float z1 = v2.z - v1.z;
- float z2 = v3.z - v1.z;
+ tangentp.normalize();
+ binormalp.normalize();
- float s1 = w2.x - w1.x;
- float s2 = w3.x - w1.x;
- float t1 = w2.y - w1.y;
- float t2 = w3.y - w1.y;
- float r = (s1 * t2 - s2 * t1);
+ for (int j=0;j<3;j++) {
+ vtx[ i[j] ]->get().binormal+=binormalp;
+ vtx[ i[j] ]->get().tangent+=tangentp;
- Vector3 binormal,tangent;
+ }
+ }
- if (r==0) {
- binormal=Vector3(0,0,0);
- tangent=Vector3(0,0,0);
- } else {
- tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
- (t2 * z1 - t1 * z2) * r);
- binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
- (s1 * z2 - s2 * z1) * r);
+ for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) {
+ E->get().binormal.normalize();
+ E->get().tangent.normalize();
}
- tangent.normalize();
- binormal.normalize();
- Vector3 normal=Plane( v1, v2, v3 ).normal;
- Vector3 tangentp = tangent - normal * normal.dot( tangent );
- Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal));
+ } else {
+
- tangentp.normalize();
- binormalp.normalize();
+ for (List<Vertex>::Element *E=vertex_array.front();E;) {
+ List< Vertex >::Element *v[3];
+ v[0]=E;
+ v[1]=v[0]->next();
+ ERR_FAIL_COND(!v[1]);
+ v[2]=v[1]->next();
+ ERR_FAIL_COND(!v[2]);
+ E=v[2]->next();
- for (int j=0;j<3;j++) {
- vertexptr[i*3+j].normal=normal;
- vertexptr[i*3+j].binormal=binormalp;
- vertexptr[i*3+j].tangent=tangentp;
+ Vector3 v1 = v[0]->get().vertex;
+ Vector3 v2 = v[1]->get().vertex;
+ Vector3 v3 = v[2]->get().vertex;
+
+ Vector2 w1 = v[0]->get().uv;
+ Vector2 w2 = v[1]->get().uv;
+ Vector2 w3 = v[2]->get().uv;
+
+
+ float x1 = v2.x - v1.x;
+ float x2 = v3.x - v1.x;
+ float y1 = v2.y - v1.y;
+ float y2 = v3.y - v1.y;
+ float z1 = v2.z - v1.z;
+ float z2 = v3.z - v1.z;
+
+ float s1 = w2.x - w1.x;
+ float s2 = w3.x - w1.x;
+ float t1 = w2.y - w1.y;
+ float t2 = w3.y - w1.y;
+
+ float r = (s1 * t2 - s2 * t1);
+
+ Vector3 binormal,tangent;
+
+ if (r==0) {
+ binormal=Vector3(0,0,0);
+ tangent=Vector3(0,0,0);
+ } else {
+ tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
+ binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
+ }
+
+ tangent.normalize();
+ binormal.normalize();
+ Vector3 normal=Plane( v1, v2, v3 ).normal;
+
+ Vector3 tangentp = tangent - normal * normal.dot( tangent );
+ Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal));
+
+ tangentp.normalize();
+ binormalp.normalize();
+
+
+ for (int j=0;j<3;j++) {
+ v[j]->get().binormal=binormalp;
+ v[j]->get().tangent=tangentp;
+
+ }
}
}
- format|=Surface::ARRAY_FORMAT_TANGENT;
- printf("adding tangents to the format\n");
+ format|=Mesh::ARRAY_FORMAT_TANGENT;
- vertex_array.write_unlock();
-#endif
}
-void SurfaceTool::generate_flat_normals() {
+void SurfaceTool::generate_normals() {
-}
-void SurfaceTool::generate_smooth_normals() {
+ ERR_FAIL_COND(primitive!=Mesh::PRIMITIVE_TRIANGLES);
+
+ bool was_indexed=index_array.size();
+
+ deindex();
+
+ HashMap<Vertex,Vector3,VertexHasher> vertex_hash;
+
+ int count=0;
+ bool smooth=false;
+ if (smooth_groups.has(0))
+ smooth=smooth_groups[0];
+
+ print_line("SMOOTH BEGIN? "+itos(smooth));
+
+ List< Vertex >::Element *B=vertex_array.front();
+ for(List< Vertex >::Element *E=B;E;) {
+
+ List< Vertex >::Element *v[3];
+ v[0]=E;
+ v[1]=v[0]->next();
+ ERR_FAIL_COND(!v[1]);
+ v[2]=v[1]->next();
+ ERR_FAIL_COND(!v[2]);
+ E=v[2]->next();
+
+ Vector3 normal = Plane(v[0]->get().vertex,v[1]->get().vertex,v[2]->get().vertex).normal;
+
+ if (smooth) {
+
+ for(int i=0;i<3;i++) {
+
+ Vector3 *lv=vertex_hash.getptr(v[i]->get());
+ if (!lv) {
+ vertex_hash.set(v[i]->get(),normal);
+ } else {
+ (*lv)+=normal;
+ }
+ }
+ } else {
+
+ for(int i=0;i<3;i++) {
+
+ v[i]->get().normal=normal;
+
+ }
+ }
+ count+=3;
+
+ if (smooth_groups.has(count) || !E) {
+
+ if (vertex_hash.size()) {
+
+ while (B!=E) {
+
+
+ Vector3* lv=vertex_hash.getptr(B->get());
+ if (lv) {
+ B->get().normal=lv->normalized();
+ }
+
+ B=B->next();
+ }
+
+ } else {
+ B=E;
+ }
+
+ vertex_hash.clear();
+ if (E) {
+ smooth=smooth_groups[count];
+ print_line("SMOOTH AT "+itos(count)+": "+itos(smooth));
+
+ }
+ }
+
+ }
+
+ format|=Mesh::ARRAY_FORMAT_NORMAL;
+
+ if (was_indexed) {
+ index();
+ smooth_groups.clear();
+ }
}
@@ -722,6 +876,7 @@ void SurfaceTool::clear() {
last_weights.clear();
index_array.clear();
vertex_array.clear();
+ smooth_groups.clear();
}
@@ -736,12 +891,12 @@ void SurfaceTool::_bind_methods() {
ObjectTypeDB::bind_method(_MD("add_uv2","uv2"),&SurfaceTool::add_uv2);
ObjectTypeDB::bind_method(_MD("add_bones","bones"),&SurfaceTool::add_bones);
ObjectTypeDB::bind_method(_MD("add_weights","weights"),&SurfaceTool::add_weights);
+ ObjectTypeDB::bind_method(_MD("add_smooth_group","smooth"),&SurfaceTool::add_smooth_group);
ObjectTypeDB::bind_method(_MD("set_material","material:Material"),&SurfaceTool::set_material);
ObjectTypeDB::bind_method(_MD("index"),&SurfaceTool::index);
ObjectTypeDB::bind_method(_MD("deindex"),&SurfaceTool::deindex);
- ObjectTypeDB::bind_method(_MD("generate_flat_normals"),&SurfaceTool::generate_flat_normals);
- ObjectTypeDB::bind_method(_MD("generate_smooth_normals"),&SurfaceTool::generate_smooth_normals);
- ObjectTypeDB::bind_method(_MD("generate_tangents"),&SurfaceTool::generate_tangents);
+ ///ObjectTypeDB::bind_method(_MD("generate_flat_normals"),&SurfaceTool::generate_flat_normals);
+ ObjectTypeDB::bind_method(_MD("generate_normals"),&SurfaceTool::generate_normals);
ObjectTypeDB::bind_method(_MD("commit:Mesh","existing:Mesh"),&SurfaceTool::commit,DEFVAL( RefPtr() ));
ObjectTypeDB::bind_method(_MD("clear"),&SurfaceTool::clear);
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 8f0fcaa01a..fe82d3a4ce 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -49,12 +49,17 @@ public:
Vector<int> bones;
Vector<float> weights;
+ bool operator==(const Vertex& p_vertex) const;
+
Vertex() { }
};
private:
- bool compare(const Vertex& p_a,const Vertex& p_b) const;
+
+ struct VertexHasher {
+ static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx);
+ };
bool begun;
bool first;
@@ -64,6 +69,7 @@ private:
//arrays
List< Vertex > vertex_array;
List< int > index_array;
+ Map<int,bool> smooth_groups;
//memory
Color last_color;
@@ -92,13 +98,13 @@ public:
void add_uv2( const Vector2& p_uv);
void add_bones( const Vector<int>& p_indices);
void add_weights( const Vector<float>& p_weights);
+ void add_smooth_group(bool p_smooth);
void add_index( int p_index);
void index();
void deindex();
- void generate_flat_normals();
- void generate_smooth_normals();
+ void generate_normals();
void generate_tangents();
void add_to_format(int p_flags) { format|=p_flags; }
diff --git a/servers/audio/audio_mixer_sw.cpp b/servers/audio/audio_mixer_sw.cpp
index 2ca0c5e93a..873e19823a 100644
--- a/servers/audio/audio_mixer_sw.cpp
+++ b/servers/audio/audio_mixer_sw.cpp
@@ -35,7 +35,7 @@
#define NO_REVERB
#endif
-template<class Depth,bool is_stereo,bool use_filter,bool use_fx,AudioMixerSW::InterpolationType type,AudioMixerSW::MixChannels mix_mode>
+template<class Depth,bool is_stereo,bool is_ima_adpcm,bool use_filter,bool use_fx,AudioMixerSW::InterpolationType type,AudioMixerSW::MixChannels mix_mode>
void AudioMixerSW::do_resample(const Depth* p_src, int32_t *p_dst, ResamplerState *p_state) {
// this function will be compiled branchless by any decent compiler
@@ -48,37 +48,110 @@ void AudioMixerSW::do_resample(const Depth* p_src, int32_t *p_dst, ResamplerStat
if (is_stereo)
pos<<=1;
- final=p_src[pos];
- if (is_stereo)
- final_r=p_src[pos+1];
+ if (is_ima_adpcm) {
- if (sizeof(Depth)==1) { /* conditions will not exist anymore when compiled! */
- final<<=8;
- if (is_stereo)
- final_r<<=8;
- }
+ int sample_pos = pos + p_state->ima_adpcm->window_ofs;
- if (type==INTERPOLATION_LINEAR) {
+ while(sample_pos>p_state->ima_adpcm->last_nibble) {
- if (is_stereo) {
- next=p_src[pos+2];
- next_r=p_src[pos+3];
- } else {
- next=p_src[pos+1];
+ static const int16_t _ima_adpcm_step_table[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+ };
+
+ static const int8_t _ima_adpcm_index_table[16] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+ };
+
+ int16_t nibble,signed_nibble,diff,step;
+
+ p_state->ima_adpcm->last_nibble++;
+ const uint8_t *src_ptr=p_state->ima_adpcm->ptr;
+
+ nibble = (p_state->ima_adpcm->last_nibble&1)?
+ (src_ptr[p_state->ima_adpcm->last_nibble>>1]>>4):(src_ptr[p_state->ima_adpcm->last_nibble>>1]&0xF);
+ step=_ima_adpcm_step_table[p_state->ima_adpcm->step_index];
+
+ p_state->ima_adpcm->step_index += _ima_adpcm_index_table[nibble];
+ if (p_state->ima_adpcm->step_index<0)
+ p_state->ima_adpcm->step_index=0;
+ if (p_state->ima_adpcm->step_index>88)
+ p_state->ima_adpcm->step_index=88;
+
+ /*
+ signed_nibble = (nibble&7) * ((nibble&8)?-1:1);
+ diff = (2 * signed_nibble + 1) * step / 4; */
+
+ diff = step >> 3 ;
+ if (nibble & 1)
+ diff += step >> 2 ;
+ if (nibble & 2)
+ diff += step >> 1 ;
+ if (nibble & 4)
+ diff += step ;
+ if (nibble & 8)
+ diff = -diff ;
+
+ p_state->ima_adpcm->predictor+=diff;
+ if (p_state->ima_adpcm->predictor<-0x8000)
+ p_state->ima_adpcm->predictor=-0x8000;
+ else if (p_state->ima_adpcm->predictor>0x7FFF)
+ p_state->ima_adpcm->predictor=0x7FFF;
+
+
+ /* store loop if there */
+ if (p_state->ima_adpcm->last_nibble==p_state->ima_adpcm->loop_pos) {
+
+ p_state->ima_adpcm->loop_step_index = p_state->ima_adpcm->step_index;
+ p_state->ima_adpcm->loop_predictor = p_state->ima_adpcm->predictor;
+ }
+
}
- if (sizeof(Depth)==1) {
- next<<=8;
+ final=p_state->ima_adpcm->predictor;
+
+ } else {
+ final=p_src[pos];
+ if (is_stereo)
+ final_r=p_src[pos+1];
+
+ if (sizeof(Depth)==1) { /* conditions will not exist anymore when compiled! */
+ final<<=8;
if (is_stereo)
- next_r<<=8;
+ final_r<<=8;
}
- int32_t frac=int32_t(p_state->pos&MIX_FRAC_MASK);
+ if (type==INTERPOLATION_LINEAR) {
- final=final+((next-final)*frac >> MIX_FRAC_BITS);
- if (is_stereo)
- final_r=final_r+((next_r-final_r)*frac >> MIX_FRAC_BITS);
+ if (is_stereo) {
+
+ next=p_src[pos+2];
+ next_r=p_src[pos+3];
+ } else {
+ next=p_src[pos+1];
+ }
+
+ if (sizeof(Depth)==1) {
+ next<<=8;
+ if (is_stereo)
+ next_r<<=8;
+ }
+
+ int32_t frac=int32_t(p_state->pos&MIX_FRAC_MASK);
+
+ final=final+((next-final)*frac >> MIX_FRAC_BITS);
+ if (is_stereo)
+ final_r=final_r+((next_r-final_r)*frac >> MIX_FRAC_BITS);
+ }
}
if (use_filter) {
@@ -314,6 +387,15 @@ void AudioMixerSW::mix_channel(Channel& c) {
rstate.filter_l=&c.mix.filter_l;
rstate.filter_r=&c.mix.filter_r;
+ if (format==AS::SAMPLE_FORMAT_IMA_ADPCM) {
+
+ rstate.ima_adpcm=&c.mix.ima_adpcm;
+ if (loop_format!=AS::SAMPLE_LOOP_NONE) {
+ c.mix.ima_adpcm.loop_pos=loop_begin_fp>>MIX_FRAC_BITS;
+ loop_format=AS::SAMPLE_LOOP_FORWARD;
+ }
+ }
+
while (todo>0) {
int64_t limit=0;
@@ -354,7 +436,14 @@ void AudioMixerSW::mix_channel(Channel& c) {
} else {
/* go to loop-begin */
- c.mix.offset=loop_begin_fp+(c.mix.offset-loop_end_fp);
+ if (format==AS::SAMPLE_FORMAT_IMA_ADPCM) {
+ c.mix.ima_adpcm.step_index=c.mix.ima_adpcm.loop_step_index;
+ c.mix.ima_adpcm.predictor=c.mix.ima_adpcm.loop_predictor;
+ c.mix.ima_adpcm.last_nibble=loop_begin_fp>>MIX_FRAC_BITS;
+ c.mix.offset=loop_begin_fp;
+ } else {
+ c.mix.offset=loop_begin_fp+(c.mix.offset-loop_end_fp);
+ }
}
} else {
@@ -393,48 +482,48 @@ void AudioMixerSW::mix_channel(Channel& c) {
/* Macros to call the resample function for all possibilities, creating a dedicated-non branchy function call for each thanks to template magic*/
-#define CALL_RESAMPLE_FUNC( m_depth, m_stereo, m_use_filter, m_use_fx, m_interp, m_mode)\
- do_resample<m_depth,m_stereo,m_use_filter,m_use_fx,m_interp, m_mode>(\
+#define CALL_RESAMPLE_FUNC( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\
+ do_resample<m_depth,m_stereo,m_ima_adpcm, m_use_filter,m_use_fx,m_interp, m_mode>(\
src_ptr,\
dst_buff,&rstate);
-#define CALL_RESAMPLE_INTERP( m_depth, m_stereo, m_use_filter, m_use_fx, m_interp, m_mode)\
+#define CALL_RESAMPLE_INTERP( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\
if(m_interp==INTERPOLATION_RAW) {\
- CALL_RESAMPLE_FUNC(m_depth,m_stereo,m_use_filter,m_use_fx,INTERPOLATION_RAW,m_mode);\
+ CALL_RESAMPLE_FUNC(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,INTERPOLATION_RAW,m_mode);\
} else if(m_interp==INTERPOLATION_LINEAR) {\
- CALL_RESAMPLE_FUNC(m_depth,m_stereo,m_use_filter,m_use_fx,INTERPOLATION_LINEAR,m_mode);\
+ CALL_RESAMPLE_FUNC(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,INTERPOLATION_LINEAR,m_mode);\
} else if(m_interp==INTERPOLATION_CUBIC) {\
- CALL_RESAMPLE_FUNC(m_depth,m_stereo,m_use_filter,m_use_fx,INTERPOLATION_CUBIC,m_mode);\
+ CALL_RESAMPLE_FUNC(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,INTERPOLATION_CUBIC,m_mode);\
}\
-#define CALL_RESAMPLE_FX( m_depth, m_stereo, m_use_filter, m_use_fx, m_interp, m_mode)\
+#define CALL_RESAMPLE_FX( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\
if(m_use_fx) {\
- CALL_RESAMPLE_INTERP(m_depth,m_stereo,m_use_filter,true,m_interp, m_mode);\
+ CALL_RESAMPLE_INTERP(m_depth,m_stereo, m_ima_adpcm,m_use_filter,true,m_interp, m_mode);\
} else {\
- CALL_RESAMPLE_INTERP(m_depth,m_stereo,m_use_filter,false,m_interp, m_mode);\
+ CALL_RESAMPLE_INTERP(m_depth,m_stereo, m_ima_adpcm,m_use_filter,false,m_interp, m_mode);\
}\
-#define CALL_RESAMPLE_FILTER( m_depth, m_stereo, m_use_filter, m_use_fx, m_interp, m_mode)\
+#define CALL_RESAMPLE_FILTER( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\
if(m_use_filter) {\
- CALL_RESAMPLE_FX(m_depth,m_stereo,true,m_use_fx,m_interp, m_mode);\
+ CALL_RESAMPLE_FX(m_depth,m_stereo, m_ima_adpcm,true,m_use_fx,m_interp, m_mode);\
} else {\
- CALL_RESAMPLE_FX(m_depth,m_stereo,false,m_use_fx,m_interp, m_mode);\
+ CALL_RESAMPLE_FX(m_depth,m_stereo, m_ima_adpcm,false,m_use_fx,m_interp, m_mode);\
}\
-#define CALL_RESAMPLE_STEREO( m_depth, m_stereo, m_use_filter, m_use_fx, m_interp, m_mode)\
+#define CALL_RESAMPLE_STEREO( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\
if(m_stereo) {\
- CALL_RESAMPLE_FILTER(m_depth,true,m_use_filter,m_use_fx,m_interp, m_mode);\
+ CALL_RESAMPLE_FILTER(m_depth,true,m_ima_adpcm, m_use_filter,m_use_fx,m_interp, m_mode);\
} else {\
- CALL_RESAMPLE_FILTER(m_depth,false,m_use_filter,m_use_fx,m_interp, m_mode);\
+ CALL_RESAMPLE_FILTER(m_depth,false,m_ima_adpcm,m_use_filter,m_use_fx,m_interp, m_mode);\
}\
-#define CALL_RESAMPLE_MODE( m_depth, m_stereo, m_use_filter, m_use_fx, m_interp, m_mode)\
+#define CALL_RESAMPLE_MODE( m_depth, m_stereo, m_ima_adpcm, m_use_filter, m_use_fx, m_interp, m_mode)\
if(m_mode==MIX_STEREO) {\
- CALL_RESAMPLE_STEREO(m_depth,m_stereo,m_use_filter,m_use_fx,m_interp, MIX_STEREO);\
+ CALL_RESAMPLE_STEREO(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,m_interp, MIX_STEREO);\
} else {\
- CALL_RESAMPLE_STEREO(m_depth,m_stereo,m_use_filter,m_use_fx,m_interp, MIX_QUAD);\
+ CALL_RESAMPLE_STEREO(m_depth,m_stereo, m_ima_adpcm,m_use_filter,m_use_fx,m_interp, MIX_QUAD);\
}\
@@ -443,11 +532,17 @@ void AudioMixerSW::mix_channel(Channel& c) {
if (format==AS::SAMPLE_FORMAT_PCM8) {
int8_t *src_ptr = &((int8_t*)data)[(c.mix.offset >> MIX_FRAC_BITS)<<(is_stereo?1:0) ];
- CALL_RESAMPLE_MODE(int8_t,is_stereo,use_filter,use_fx,interpolation_type,mix_channels);
+ CALL_RESAMPLE_MODE(int8_t,is_stereo,false,use_filter,use_fx,interpolation_type,mix_channels);
} else if (format==AS::SAMPLE_FORMAT_PCM16) {
int16_t *src_ptr = &((int16_t*)data)[(c.mix.offset >> MIX_FRAC_BITS)<<(is_stereo?1:0) ];
- CALL_RESAMPLE_MODE(int16_t,is_stereo,use_filter,use_fx,interpolation_type,mix_channels);
+ CALL_RESAMPLE_MODE(int16_t,is_stereo,false,use_filter,use_fx,interpolation_type,mix_channels);
+
+ } else if (format==AS::SAMPLE_FORMAT_IMA_ADPCM) {
+ c.mix.ima_adpcm.window_ofs=c.mix.offset>>MIX_FRAC_BITS;
+ c.mix.ima_adpcm.ptr=(const uint8_t*)data;
+ int8_t *src_ptr = &((int8_t*)data)[(c.mix.offset >> MIX_FRAC_BITS)<<(is_stereo?1:0) ];
+ CALL_RESAMPLE_MODE(int8_t,false,true,use_filter,use_fx,interpolation_type,mix_channels);
}
@@ -669,6 +764,19 @@ AudioMixer::ChannelID AudioMixerSW::channel_alloc(RID p_sample) {
c.had_prev_reverb=false;
c.had_prev_vol=false;
+
+ if (sample_manager->sample_get_format(c.sample)==AudioServer::SAMPLE_FORMAT_IMA_ADPCM) {
+
+ c.mix.ima_adpcm.step_index=0;
+ c.mix.ima_adpcm.predictor=0;
+ c.mix.ima_adpcm.loop_step_index=0;
+ c.mix.ima_adpcm.loop_predictor=0;
+ c.mix.ima_adpcm.last_nibble=-1;
+ c.mix.ima_adpcm.loop_pos=0x7FFFFFFF;
+ c.mix.ima_adpcm.window_ofs=0;
+ c.mix.ima_adpcm.ptr=NULL;
+ }
+
ChannelID ret_id = index+c.check*MAX_CHANNELS;
return ret_id;
diff --git a/servers/audio/audio_mixer_sw.h b/servers/audio/audio_mixer_sw.h
index eb3feee1c8..d3caf03089 100644
--- a/servers/audio/audio_mixer_sw.h
+++ b/servers/audio/audio_mixer_sw.h
@@ -73,6 +73,7 @@ private:
MAX_REVERBS=4
};
+
struct Channel {
RID sample;
@@ -93,6 +94,19 @@ private:
float ha[2],hb[2];
} filter_l,filter_r;
+ struct IMA_ADPCM_State {
+
+ int16_t step_index;
+ int32_t predictor;
+ /* values at loop point */
+ int16_t loop_step_index;
+ int32_t loop_predictor;
+ int32_t last_nibble;
+ int32_t loop_pos;
+ int32_t window_ofs;
+ const uint8_t *ptr;
+ } ima_adpcm;
+
} mix;
float vol;
@@ -163,17 +177,20 @@ private:
int32_t chorus_vol_inc[4];
+
Channel::Mix::Filter *filter_l;
Channel::Mix::Filter *filter_r;
Channel::Filter::Coefs coefs;
Channel::Filter::Coefs coefs_inc;
+ Channel::Mix::IMA_ADPCM_State *ima_adpcm;
+
int32_t *reverb_buffer;
};
- template<class Depth,bool is_stereo,bool use_filter,bool use_fx,InterpolationType type,MixChannels>
+ template<class Depth,bool is_stereo,bool use_filter,bool is_ima_adpcm,bool use_fx,InterpolationType type,MixChannels>
_FORCE_INLINE_ void do_resample(const Depth* p_src, int32_t *p_dst, ResamplerState *p_state);
MixChannels mix_channels;
diff --git a/servers/audio/sample_manager_sw.cpp b/servers/audio/sample_manager_sw.cpp
index 2c065a9375..5a5aa1a34c 100644
--- a/servers/audio/sample_manager_sw.cpp
+++ b/servers/audio/sample_manager_sw.cpp
@@ -46,8 +46,13 @@ RID SampleManagerMallocSW::sample_create(AS::SampleFormat p_format, bool p_stere
datalen*=2;
if (p_format==AS::SAMPLE_FORMAT_PCM16)
datalen*=2;
- else if (p_format==AS::SAMPLE_FORMAT_IMA_ADPCM)
+ else if (p_format==AS::SAMPLE_FORMAT_IMA_ADPCM) {
+ if (datalen&1) {
+ datalen++;
+ }
datalen/=2;
+ datalen+=4;
+ }
#define SAMPLE_EXTRA 16
s->data = memalloc(datalen+SAMPLE_EXTRA); //help the interpolator by allocating a little more..
@@ -128,11 +133,13 @@ void SampleManagerMallocSW::sample_set_data(RID p_sample, const DVector<uint8_t>
int buff_size=p_buffer.size();
ERR_FAIL_COND(buff_size==0);
+
ERR_EXPLAIN("Sample buffer size does not match sample size.");
ERR_FAIL_COND(s->length_bytes!=buff_size);
DVector<uint8_t>::Read buffer_r=p_buffer.read();
const uint8_t *src = buffer_r.ptr();
uint8_t *dst = (uint8_t*)s->data;
+ print_line("set data: "+itos(s->length_bytes));
for(int i=0;i<s->length_bytes;i++) {
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index f0f72b471c..52edc0faa7 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -425,6 +425,27 @@ void BodySW::integrate_velocities(real_t p_step) {
return;
}
+
+
+ //apply axis lock
+ if (axis_lock!=PhysicsServer::BODY_AXIS_LOCK_DISABLED) {
+
+
+ int axis=axis_lock-1;
+ for(int i=0;i<3;i++) {
+ if (i==axis) {
+ linear_velocity[i]=0;
+ biased_linear_velocity[i]=0;
+ } else {
+
+ angular_velocity[i]=0;
+ biased_angular_velocity[i]=0;
+ }
+ }
+
+ }
+
+
Vector3 total_angular_velocity = angular_velocity+biased_angular_velocity;
@@ -441,7 +462,11 @@ void BodySW::integrate_velocities(real_t p_step) {
}
Vector3 total_linear_velocity=linear_velocity+biased_linear_velocity;
-
+ /*for(int i=0;i<3;i++) {
+ if (axis_lock&(1<<i)) {
+ transform.origin[i]=0.0;
+ }
+ }*/
transform.origin+=total_linear_velocity * p_step;
@@ -614,6 +639,7 @@ BodySW::BodySW() : CollisionObjectSW(TYPE_BODY), active_list(this), inertia_upda
continuous_cd=false;
can_sleep=false;
fi_callback=NULL;
+ axis_lock=PhysicsServer::BODY_AXIS_LOCK_DISABLED;
}
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index 9f0bbc00cf..8923899278 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -26,323 +26,328 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef BODY_SW_H
-#define BODY_SW_H
-
-#include "collision_object_sw.h"
-#include "vset.h"
-#include "area_sw.h"
-
-class ConstraintSW;
-
-
-class BodySW : public CollisionObjectSW {
-
-
- PhysicsServer::BodyMode mode;
-
- Vector3 linear_velocity;
- Vector3 angular_velocity;
-
- Vector3 biased_linear_velocity;
- Vector3 biased_angular_velocity;
- real_t mass;
- real_t bounce;
- real_t friction;
-
- real_t _inv_mass;
- Vector3 _inv_inertia;
- Matrix3 _inv_inertia_tensor;
-
- Vector3 gravity;
- real_t density;
-
- real_t still_time;
-
- Vector3 applied_force;
- Vector3 applied_torque;
-
- SelfList<BodySW> active_list;
- SelfList<BodySW> inertia_update_list;
- SelfList<BodySW> direct_state_query_list;
-
- VSet<RID> exceptions;
- bool omit_force_integration;
- bool active;
- bool simulated_motion;
- bool continuous_cd;
- bool can_sleep;
- void _update_inertia();
- virtual void _shapes_changed();
-
- Map<ConstraintSW*,int> constraint_map;
-
- struct AreaCMP {
-
- AreaSW *area;
- _FORCE_INLINE_ bool operator<(const AreaCMP& p_cmp) const { return area->get_self() < p_cmp.area->get_self() ; }
- _FORCE_INLINE_ AreaCMP() {}
- _FORCE_INLINE_ AreaCMP(AreaSW *p_area) { area=p_area;}
- };
-
-
- VSet<AreaCMP> areas;
-
- struct Contact {
-
-
- Vector3 local_pos;
- Vector3 local_normal;
- float depth;
- int local_shape;
- Vector3 collider_pos;
- int collider_shape;
- ObjectID collider_instance_id;
- RID collider;
- Vector3 collider_velocity_at_pos;
- };
-
- Vector<Contact> contacts; //no contacts by default
- int contact_count;
-
- struct ForceIntegrationCallback {
-
- ObjectID id;
- StringName method;
- Variant udata;
- };
-
- ForceIntegrationCallback *fi_callback;
-
-
- uint64_t island_step;
- BodySW *island_next;
- BodySW *island_list_next;
-
- _FORCE_INLINE_ void _compute_area_gravity(const AreaSW *p_area);
-
- _FORCE_INLINE_ void _update_inertia_tensor();
-
-friend class PhysicsDirectBodyStateSW; // i give up, too many functions to expose
-
-public:
-
-
- void set_force_integration_callback(ObjectID p_id,const StringName& p_method,const Variant& p_udata=Variant());
-
-
- _FORCE_INLINE_ void add_area(AreaSW *p_area) { areas.insert(AreaCMP(p_area)); }
- _FORCE_INLINE_ void remove_area(AreaSW *p_area) { areas.erase(AreaCMP(p_area)); }
-
- _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; }
- _FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
-
- _FORCE_INLINE_ bool can_report_contacts() const { return !contacts.empty(); }
- _FORCE_INLINE_ void add_contact(const Vector3& p_local_pos,const Vector3& p_local_normal, float p_depth, int p_local_shape, const Vector3& p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID& p_collider,const Vector3& p_collider_velocity_at_pos);
-
-
- _FORCE_INLINE_ void add_exception(const RID& p_exception) { exceptions.insert(p_exception);}
- _FORCE_INLINE_ void remove_exception(const RID& p_exception) { exceptions.erase(p_exception);}
- _FORCE_INLINE_ bool has_exception(const RID& p_exception) const { return exceptions.has(p_exception);}
- _FORCE_INLINE_ const VSet<RID>& get_exceptions() const { return exceptions;}
-
- _FORCE_INLINE_ uint64_t get_island_step() const { return island_step; }
- _FORCE_INLINE_ void set_island_step(uint64_t p_step) { island_step=p_step; }
-
- _FORCE_INLINE_ BodySW* get_island_next() const { return island_next; }
- _FORCE_INLINE_ void set_island_next(BodySW* p_next) { island_next=p_next; }
-
- _FORCE_INLINE_ BodySW* get_island_list_next() const { return island_list_next; }
- _FORCE_INLINE_ void set_island_list_next(BodySW* p_next) { island_list_next=p_next; }
-
- _FORCE_INLINE_ void add_constraint(ConstraintSW* p_constraint, int p_pos) { constraint_map[p_constraint]=p_pos; }
- _FORCE_INLINE_ void remove_constraint(ConstraintSW* p_constraint) { constraint_map.erase(p_constraint); }
- const Map<ConstraintSW*,int>& get_constraint_map() const { return constraint_map; }
-
- _FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration=p_omit_force_integration; }
- _FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
-
- _FORCE_INLINE_ void set_linear_velocity(const Vector3& p_velocity) {linear_velocity=p_velocity; }
- _FORCE_INLINE_ Vector3 get_linear_velocity() const { return linear_velocity; }
-
- _FORCE_INLINE_ void set_angular_velocity(const Vector3& p_velocity) { angular_velocity=p_velocity; }
- _FORCE_INLINE_ Vector3 get_angular_velocity() const { return angular_velocity; }
-
- _FORCE_INLINE_ const Vector3& get_biased_linear_velocity() const { return biased_linear_velocity; }
- _FORCE_INLINE_ const Vector3& get_biased_angular_velocity() const { return biased_angular_velocity; }
-
- _FORCE_INLINE_ void apply_impulse(const Vector3& p_pos, const Vector3& p_j) {
-
- linear_velocity += p_j * _inv_mass;
- angular_velocity += _inv_inertia_tensor.xform( p_pos.cross(p_j) );
- }
-
- _FORCE_INLINE_ void apply_bias_impulse(const Vector3& p_pos, const Vector3& p_j) {
-
- biased_linear_velocity += p_j * _inv_mass;
- biased_angular_velocity += _inv_inertia_tensor.xform( p_pos.cross(p_j) );
- }
-
- _FORCE_INLINE_ void apply_torque_impulse(const Vector3& p_j) {
-
- angular_velocity += _inv_inertia_tensor.xform(p_j);
- }
-
- _FORCE_INLINE_ void add_force(const Vector3& p_force, const Vector3& p_pos) {
-
- applied_force += p_force;
- applied_torque += p_pos.cross(p_force);
- }
-
- void set_active(bool p_active);
- _FORCE_INLINE_ bool is_active() const { return active; }
-
- void set_param(PhysicsServer::BodyParameter p_param, float);
- float get_param(PhysicsServer::BodyParameter p_param) const;
-
- void set_mode(PhysicsServer::BodyMode p_mode);
- PhysicsServer::BodyMode get_mode() const;
-
- void set_state(PhysicsServer::BodyState p_state, const Variant& p_variant);
- Variant get_state(PhysicsServer::BodyState p_state) const;
-
- void set_applied_force(const Vector3& p_force) { applied_force=p_force; }
- Vector3 get_applied_force() const { return applied_force; }
-
- void set_applied_torque(const Vector3& p_torque) { applied_torque=p_torque; }
- Vector3 get_applied_torque() const { return applied_torque; }
-
- _FORCE_INLINE_ void set_continuous_collision_detection(bool p_enable) { continuous_cd=p_enable; }
- _FORCE_INLINE_ bool is_continuous_collision_detection_enabled() const { return continuous_cd; }
-
- void set_space(SpaceSW *p_space);
-
- void update_inertias();
-
- _FORCE_INLINE_ real_t get_inv_mass() const { return _inv_mass; }
- _FORCE_INLINE_ Vector3 get_inv_inertia() const { return _inv_inertia; }
- _FORCE_INLINE_ Matrix3 get_inv_inertia_tensor() const { return _inv_inertia_tensor; }
- _FORCE_INLINE_ real_t get_friction() const { return friction; }
- _FORCE_INLINE_ Vector3 get_gravity() const { return gravity; }
- _FORCE_INLINE_ real_t get_density() const { return density; }
- _FORCE_INLINE_ real_t get_bounce() const { return bounce; }
-
- void integrate_forces(real_t p_step);
- void integrate_velocities(real_t p_step);
-
- void simulate_motion(const Transform& p_xform,real_t p_step);
- void call_queries();
- void wakeup_neighbours();
-
- bool sleep_test(real_t p_step);
-
- BodySW();
- ~BodySW();
-
-};
-
-
-//add contact inline
-
-void BodySW::add_contact(const Vector3& p_local_pos,const Vector3& p_local_normal, float p_depth, int p_local_shape, const Vector3& p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID& p_collider,const Vector3& p_collider_velocity_at_pos) {
-
- int c_max=contacts.size();
-
- if (c_max==0)
- return;
-
- Contact *c = &contacts[0];
-
-
- int idx=-1;
-
- if (contact_count<c_max) {
- idx=contact_count++;
- } else {
-
- float least_depth=1e20;
- int least_deep=-1;
- for(int i=0;i<c_max;i++) {
-
- if (i==0 || c[i].depth<least_depth) {
- least_deep=i;
- least_depth=c[i].depth;
- }
- }
-
- if (least_deep>=0 && least_depth<p_depth) {
-
- idx=least_deep;
- }
- if (idx==-1)
- return; //none least deepe than this
- }
-
- c[idx].local_pos=p_local_pos;
- c[idx].local_normal=p_local_normal;
- c[idx].depth=p_depth;
- c[idx].local_shape=p_local_shape;
- c[idx].collider_pos=p_collider_pos;
- c[idx].collider_shape=p_collider_shape;
- c[idx].collider_instance_id=p_collider_instance_id;
- c[idx].collider=p_collider;
- c[idx].collider_velocity_at_pos=p_collider_velocity_at_pos;
-
-}
-
-
-class PhysicsDirectBodyStateSW : public PhysicsDirectBodyState {
-
- OBJ_TYPE( PhysicsDirectBodyStateSW, PhysicsDirectBodyState );
-
-public:
-
- static PhysicsDirectBodyStateSW *singleton;
- BodySW *body;
- real_t step;
-
- virtual Vector3 get_total_gravity() const { return body->get_gravity(); } // get gravity vector working on this body space/area
- virtual float get_total_density() const { return body->get_density(); } // get density of this body space/area
-
- virtual float get_inverse_mass() const { return body->get_inv_mass(); } // get the mass
- virtual Vector3 get_inverse_inertia() const { return body->get_inv_inertia(); } // get density of this body space
- virtual Matrix3 get_inverse_inertia_tensor() const { return body->get_inv_inertia_tensor(); } // get density of this body space
-
- virtual void set_linear_velocity(const Vector3& p_velocity) { body->set_linear_velocity(p_velocity); }
- virtual Vector3 get_linear_velocity() const { return body->get_linear_velocity(); }
-
- virtual void set_angular_velocity(const Vector3& p_velocity) { body->set_angular_velocity(p_velocity); }
- virtual Vector3 get_angular_velocity() const { return body->get_angular_velocity(); }
-
- virtual void set_transform(const Transform& p_transform) { body->set_state(PhysicsServer::BODY_STATE_TRANSFORM,p_transform); }
- virtual Transform get_transform() const { return body->get_transform(); }
-
- virtual void add_force(const Vector3& p_force, const Vector3& p_pos) { body->add_force(p_force,p_pos); }
-
- virtual void set_sleep_state(bool p_enable) { body->set_active(!p_enable); }
- virtual bool is_sleeping() const { return !body->is_active(); }
-
- virtual int get_contact_count() const { return body->contact_count; }
-
- virtual Vector3 get_contact_local_pos(int p_contact_idx) const {
- ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector3());
- return body->contacts[p_contact_idx].local_pos;
- }
- virtual Vector3 get_contact_local_normal(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector3()); return body->contacts[p_contact_idx].local_normal; }
- virtual int get_contact_local_shape(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,-1); return body->contacts[p_contact_idx].local_shape; }
-
- virtual RID get_contact_collider(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,RID()); return body->contacts[p_contact_idx].collider; }
- virtual Vector3 get_contact_collider_pos(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector3()); return body->contacts[p_contact_idx].collider_pos; }
- virtual ObjectID get_contact_collider_id(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,0); return body->contacts[p_contact_idx].collider_instance_id; }
- virtual int get_contact_collider_shape(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,0); return body->contacts[p_contact_idx].collider_shape; }
- virtual Vector3 get_contact_collider_velocity_at_pos(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector3()); return body->contacts[p_contact_idx].collider_velocity_at_pos; }
-
- virtual PhysicsDirectSpaceState* get_space_state();
-
-
- virtual real_t get_step() const { return step; }
- PhysicsDirectBodyStateSW() { singleton=this; body=NULL; }
-};
-
-
-#endif // BODY__SW_H
+#ifndef BODY_SW_H
+#define BODY_SW_H
+
+#include "collision_object_sw.h"
+#include "vset.h"
+#include "area_sw.h"
+
+class ConstraintSW;
+
+
+class BodySW : public CollisionObjectSW {
+
+
+ PhysicsServer::BodyMode mode;
+
+ Vector3 linear_velocity;
+ Vector3 angular_velocity;
+
+ Vector3 biased_linear_velocity;
+ Vector3 biased_angular_velocity;
+ real_t mass;
+ real_t bounce;
+ real_t friction;
+
+ PhysicsServer::BodyAxisLock axis_lock;
+
+ real_t _inv_mass;
+ Vector3 _inv_inertia;
+ Matrix3 _inv_inertia_tensor;
+
+ Vector3 gravity;
+ real_t density;
+
+ real_t still_time;
+
+ Vector3 applied_force;
+ Vector3 applied_torque;
+
+ SelfList<BodySW> active_list;
+ SelfList<BodySW> inertia_update_list;
+ SelfList<BodySW> direct_state_query_list;
+
+ VSet<RID> exceptions;
+ bool omit_force_integration;
+ bool active;
+ bool simulated_motion;
+ bool continuous_cd;
+ bool can_sleep;
+ void _update_inertia();
+ virtual void _shapes_changed();
+
+ Map<ConstraintSW*,int> constraint_map;
+
+ struct AreaCMP {
+
+ AreaSW *area;
+ _FORCE_INLINE_ bool operator<(const AreaCMP& p_cmp) const { return area->get_self() < p_cmp.area->get_self() ; }
+ _FORCE_INLINE_ AreaCMP() {}
+ _FORCE_INLINE_ AreaCMP(AreaSW *p_area) { area=p_area;}
+ };
+
+
+ VSet<AreaCMP> areas;
+
+ struct Contact {
+
+
+ Vector3 local_pos;
+ Vector3 local_normal;
+ float depth;
+ int local_shape;
+ Vector3 collider_pos;
+ int collider_shape;
+ ObjectID collider_instance_id;
+ RID collider;
+ Vector3 collider_velocity_at_pos;
+ };
+
+ Vector<Contact> contacts; //no contacts by default
+ int contact_count;
+
+ struct ForceIntegrationCallback {
+
+ ObjectID id;
+ StringName method;
+ Variant udata;
+ };
+
+ ForceIntegrationCallback *fi_callback;
+
+
+ uint64_t island_step;
+ BodySW *island_next;
+ BodySW *island_list_next;
+
+ _FORCE_INLINE_ void _compute_area_gravity(const AreaSW *p_area);
+
+ _FORCE_INLINE_ void _update_inertia_tensor();
+
+friend class PhysicsDirectBodyStateSW; // i give up, too many functions to expose
+
+public:
+
+
+ void set_force_integration_callback(ObjectID p_id,const StringName& p_method,const Variant& p_udata=Variant());
+
+
+ _FORCE_INLINE_ void add_area(AreaSW *p_area) { areas.insert(AreaCMP(p_area)); }
+ _FORCE_INLINE_ void remove_area(AreaSW *p_area) { areas.erase(AreaCMP(p_area)); }
+
+ _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; }
+ _FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
+
+ _FORCE_INLINE_ bool can_report_contacts() const { return !contacts.empty(); }
+ _FORCE_INLINE_ void add_contact(const Vector3& p_local_pos,const Vector3& p_local_normal, float p_depth, int p_local_shape, const Vector3& p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID& p_collider,const Vector3& p_collider_velocity_at_pos);
+
+
+ _FORCE_INLINE_ void add_exception(const RID& p_exception) { exceptions.insert(p_exception);}
+ _FORCE_INLINE_ void remove_exception(const RID& p_exception) { exceptions.erase(p_exception);}
+ _FORCE_INLINE_ bool has_exception(const RID& p_exception) const { return exceptions.has(p_exception);}
+ _FORCE_INLINE_ const VSet<RID>& get_exceptions() const { return exceptions;}
+
+ _FORCE_INLINE_ uint64_t get_island_step() const { return island_step; }
+ _FORCE_INLINE_ void set_island_step(uint64_t p_step) { island_step=p_step; }
+
+ _FORCE_INLINE_ BodySW* get_island_next() const { return island_next; }
+ _FORCE_INLINE_ void set_island_next(BodySW* p_next) { island_next=p_next; }
+
+ _FORCE_INLINE_ BodySW* get_island_list_next() const { return island_list_next; }
+ _FORCE_INLINE_ void set_island_list_next(BodySW* p_next) { island_list_next=p_next; }
+
+ _FORCE_INLINE_ void add_constraint(ConstraintSW* p_constraint, int p_pos) { constraint_map[p_constraint]=p_pos; }
+ _FORCE_INLINE_ void remove_constraint(ConstraintSW* p_constraint) { constraint_map.erase(p_constraint); }
+ const Map<ConstraintSW*,int>& get_constraint_map() const { return constraint_map; }
+
+ _FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration=p_omit_force_integration; }
+ _FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
+
+ _FORCE_INLINE_ void set_linear_velocity(const Vector3& p_velocity) {linear_velocity=p_velocity; }
+ _FORCE_INLINE_ Vector3 get_linear_velocity() const { return linear_velocity; }
+
+ _FORCE_INLINE_ void set_angular_velocity(const Vector3& p_velocity) { angular_velocity=p_velocity; }
+ _FORCE_INLINE_ Vector3 get_angular_velocity() const { return angular_velocity; }
+
+ _FORCE_INLINE_ const Vector3& get_biased_linear_velocity() const { return biased_linear_velocity; }
+ _FORCE_INLINE_ const Vector3& get_biased_angular_velocity() const { return biased_angular_velocity; }
+
+ _FORCE_INLINE_ void apply_impulse(const Vector3& p_pos, const Vector3& p_j) {
+
+ linear_velocity += p_j * _inv_mass;
+ angular_velocity += _inv_inertia_tensor.xform( p_pos.cross(p_j) );
+ }
+
+ _FORCE_INLINE_ void apply_bias_impulse(const Vector3& p_pos, const Vector3& p_j) {
+
+ biased_linear_velocity += p_j * _inv_mass;
+ biased_angular_velocity += _inv_inertia_tensor.xform( p_pos.cross(p_j) );
+ }
+
+ _FORCE_INLINE_ void apply_torque_impulse(const Vector3& p_j) {
+
+ angular_velocity += _inv_inertia_tensor.xform(p_j);
+ }
+
+ _FORCE_INLINE_ void add_force(const Vector3& p_force, const Vector3& p_pos) {
+
+ applied_force += p_force;
+ applied_torque += p_pos.cross(p_force);
+ }
+
+ void set_active(bool p_active);
+ _FORCE_INLINE_ bool is_active() const { return active; }
+
+ void set_param(PhysicsServer::BodyParameter p_param, float);
+ float get_param(PhysicsServer::BodyParameter p_param) const;
+
+ void set_mode(PhysicsServer::BodyMode p_mode);
+ PhysicsServer::BodyMode get_mode() const;
+
+ void set_state(PhysicsServer::BodyState p_state, const Variant& p_variant);
+ Variant get_state(PhysicsServer::BodyState p_state) const;
+
+ void set_applied_force(const Vector3& p_force) { applied_force=p_force; }
+ Vector3 get_applied_force() const { return applied_force; }
+
+ void set_applied_torque(const Vector3& p_torque) { applied_torque=p_torque; }
+ Vector3 get_applied_torque() const { return applied_torque; }
+
+ _FORCE_INLINE_ void set_continuous_collision_detection(bool p_enable) { continuous_cd=p_enable; }
+ _FORCE_INLINE_ bool is_continuous_collision_detection_enabled() const { return continuous_cd; }
+
+ void set_space(SpaceSW *p_space);
+
+ void update_inertias();
+
+ _FORCE_INLINE_ real_t get_inv_mass() const { return _inv_mass; }
+ _FORCE_INLINE_ Vector3 get_inv_inertia() const { return _inv_inertia; }
+ _FORCE_INLINE_ Matrix3 get_inv_inertia_tensor() const { return _inv_inertia_tensor; }
+ _FORCE_INLINE_ real_t get_friction() const { return friction; }
+ _FORCE_INLINE_ Vector3 get_gravity() const { return gravity; }
+ _FORCE_INLINE_ real_t get_density() const { return density; }
+ _FORCE_INLINE_ real_t get_bounce() const { return bounce; }
+
+ _FORCE_INLINE_ void set_axis_lock(PhysicsServer::BodyAxisLock p_lock) { axis_lock=p_lock; }
+ _FORCE_INLINE_ PhysicsServer::BodyAxisLock get_axis_lock() const { return axis_lock; }
+
+ void integrate_forces(real_t p_step);
+ void integrate_velocities(real_t p_step);
+
+ void simulate_motion(const Transform& p_xform,real_t p_step);
+ void call_queries();
+ void wakeup_neighbours();
+
+ bool sleep_test(real_t p_step);
+
+ BodySW();
+ ~BodySW();
+
+};
+
+
+//add contact inline
+
+void BodySW::add_contact(const Vector3& p_local_pos,const Vector3& p_local_normal, float p_depth, int p_local_shape, const Vector3& p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID& p_collider,const Vector3& p_collider_velocity_at_pos) {
+
+ int c_max=contacts.size();
+
+ if (c_max==0)
+ return;
+
+ Contact *c = &contacts[0];
+
+
+ int idx=-1;
+
+ if (contact_count<c_max) {
+ idx=contact_count++;
+ } else {
+
+ float least_depth=1e20;
+ int least_deep=-1;
+ for(int i=0;i<c_max;i++) {
+
+ if (i==0 || c[i].depth<least_depth) {
+ least_deep=i;
+ least_depth=c[i].depth;
+ }
+ }
+
+ if (least_deep>=0 && least_depth<p_depth) {
+
+ idx=least_deep;
+ }
+ if (idx==-1)
+ return; //none least deepe than this
+ }
+
+ c[idx].local_pos=p_local_pos;
+ c[idx].local_normal=p_local_normal;
+ c[idx].depth=p_depth;
+ c[idx].local_shape=p_local_shape;
+ c[idx].collider_pos=p_collider_pos;
+ c[idx].collider_shape=p_collider_shape;
+ c[idx].collider_instance_id=p_collider_instance_id;
+ c[idx].collider=p_collider;
+ c[idx].collider_velocity_at_pos=p_collider_velocity_at_pos;
+
+}
+
+
+class PhysicsDirectBodyStateSW : public PhysicsDirectBodyState {
+
+ OBJ_TYPE( PhysicsDirectBodyStateSW, PhysicsDirectBodyState );
+
+public:
+
+ static PhysicsDirectBodyStateSW *singleton;
+ BodySW *body;
+ real_t step;
+
+ virtual Vector3 get_total_gravity() const { return body->get_gravity(); } // get gravity vector working on this body space/area
+ virtual float get_total_density() const { return body->get_density(); } // get density of this body space/area
+
+ virtual float get_inverse_mass() const { return body->get_inv_mass(); } // get the mass
+ virtual Vector3 get_inverse_inertia() const { return body->get_inv_inertia(); } // get density of this body space
+ virtual Matrix3 get_inverse_inertia_tensor() const { return body->get_inv_inertia_tensor(); } // get density of this body space
+
+ virtual void set_linear_velocity(const Vector3& p_velocity) { body->set_linear_velocity(p_velocity); }
+ virtual Vector3 get_linear_velocity() const { return body->get_linear_velocity(); }
+
+ virtual void set_angular_velocity(const Vector3& p_velocity) { body->set_angular_velocity(p_velocity); }
+ virtual Vector3 get_angular_velocity() const { return body->get_angular_velocity(); }
+
+ virtual void set_transform(const Transform& p_transform) { body->set_state(PhysicsServer::BODY_STATE_TRANSFORM,p_transform); }
+ virtual Transform get_transform() const { return body->get_transform(); }
+
+ virtual void add_force(const Vector3& p_force, const Vector3& p_pos) { body->add_force(p_force,p_pos); }
+
+ virtual void set_sleep_state(bool p_enable) { body->set_active(!p_enable); }
+ virtual bool is_sleeping() const { return !body->is_active(); }
+
+ virtual int get_contact_count() const { return body->contact_count; }
+
+ virtual Vector3 get_contact_local_pos(int p_contact_idx) const {
+ ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector3());
+ return body->contacts[p_contact_idx].local_pos;
+ }
+ virtual Vector3 get_contact_local_normal(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector3()); return body->contacts[p_contact_idx].local_normal; }
+ virtual int get_contact_local_shape(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,-1); return body->contacts[p_contact_idx].local_shape; }
+
+ virtual RID get_contact_collider(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,RID()); return body->contacts[p_contact_idx].collider; }
+ virtual Vector3 get_contact_collider_pos(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector3()); return body->contacts[p_contact_idx].collider_pos; }
+ virtual ObjectID get_contact_collider_id(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,0); return body->contacts[p_contact_idx].collider_instance_id; }
+ virtual int get_contact_collider_shape(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,0); return body->contacts[p_contact_idx].collider_shape; }
+ virtual Vector3 get_contact_collider_velocity_at_pos(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector3()); return body->contacts[p_contact_idx].collider_velocity_at_pos; }
+
+ virtual PhysicsDirectSpaceState* get_space_state();
+
+
+ virtual real_t get_step() const { return step; }
+ PhysicsDirectBodyStateSW() { singleton=this; body=NULL; }
+};
+
+
+#endif // BODY__SW_H
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 072f11aa52..aff60b5881 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -695,6 +695,25 @@ void PhysicsServerSW::body_set_axis_velocity(RID p_body, const Vector3& p_axis_v
};
+
+void PhysicsServerSW::body_set_axis_lock(RID p_body,BodyAxisLock p_lock) {
+
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ body->set_axis_lock(p_lock);
+
+}
+
+PhysicsServerSW::BodyAxisLock PhysicsServerSW::body_get_axis_lock(RID p_body) const{
+
+ const BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body,BODY_AXIS_LOCK_DISABLED);
+ return body->get_axis_lock();
+
+}
+
+
+
void PhysicsServerSW::body_add_collision_exception(RID p_body, RID p_body_b) {
BodySW *body = body_owner.get(p_body);
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 2a46ba65fb..0822d76936 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -167,6 +167,9 @@ public:
virtual void body_apply_impulse(RID p_body, const Vector3& p_pos, const Vector3& p_impulse);
virtual void body_set_axis_velocity(RID p_body, const Vector3& p_axis_velocity);
+ virtual void body_set_axis_lock(RID p_body,BodyAxisLock p_lock);
+ virtual BodyAxisLock body_get_axis_lock(RID p_body) const;
+
virtual void body_add_collision_exception(RID p_body, RID p_body_b);
virtual void body_remove_collision_exception(RID p_body, RID p_body_b);
virtual void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions);
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index 669240b8da..ee169cde28 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -234,7 +234,7 @@ bool BodyPair2DSW::setup(float p_step) {
//cannot collide
- if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC)) {
+ if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC)) {
collided=false;
return false;
}
@@ -343,6 +343,11 @@ bool BodyPair2DSW::setup(float p_step) {
}
}
+ if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B)) {
+ c.active=false;
+ collided=false;
+ }
+
// Precompute normal mass, tangent mass, and bias.
real_t rnA = c.rA.dot(c.normal);
real_t rnB = c.rB.dot(c.normal);
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index e07dca472b..277a286144 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -219,4 +219,5 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) {
space=NULL;
instance_id=0;
user_mask=0;
+ layer_mask=1;
}
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index 8138cfcc69..cc7f8f50bd 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -66,6 +66,7 @@ private:
Matrix32 transform;
Matrix32 inv_transform;
uint32_t user_mask;
+ uint32_t layer_mask;
bool _static;
void _update_shapes();
@@ -121,6 +122,9 @@ public:
void set_user_mask(uint32_t p_mask) {user_mask=p_mask;}
_FORCE_INLINE_ uint32_t get_user_mask() const { return user_mask; }
+ void set_layer_mask(uint32_t p_mask) {layer_mask=p_mask;}
+ _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; }
+
void remove_shape(Shape2DSW *p_shape);
void remove_shape(int p_index);
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index ee29d3aeff..2171a9c2c4 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -652,6 +652,22 @@ uint32_t Physics2DServerSW::body_get_object_instance_ID(RID p_body) const {
return body->get_instance_id();
};
+void Physics2DServerSW::body_set_layer_mask(RID p_body, uint32_t p_flags) {
+
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ body->set_layer_mask(p_flags);
+
+};
+
+uint32_t Physics2DServerSW::body_get_layer_mask(RID p_body, uint32_t p_flags) const {
+
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body,0);
+
+ return body->get_layer_mask();
+};
+
void Physics2DServerSW::body_set_user_mask(RID p_body, uint32_t p_flags) {
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index e50bb0ab96..09ca029127 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -161,6 +161,9 @@ public:
virtual void body_set_continuous_collision_detection_mode(RID p_body,CCDMode p_mode);
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const;
+ virtual void body_set_layer_mask(RID p_body, uint32_t p_mask);
+ virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const;
+
virtual void body_set_user_mask(RID p_body, uint32_t p_mask);
virtual uint32_t body_get_user_mask(RID p_body, uint32_t p_mask) const;
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index d1aec92984..5fbf828c38 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -31,9 +31,9 @@
#include "physics_2d_server_sw.h"
-_FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_user_mask, uint32_t p_type_mask) {
+_FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) {
- if (p_user_mask && !(p_object->get_user_mask()&p_user_mask))
+ if ((p_object->get_layer_mask()&p_layer_mask)==0)
return false;
if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA && !(p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA))
@@ -45,7 +45,7 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec
}
-bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude,uint32_t p_user_mask,uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
@@ -70,7 +70,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2& p_from, const Vec
for(int i=0;i<amount;i++) {
- if (!_match_object_type_query(space->intersection_query_results[i],p_user_mask,p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
continue;
if (p_exclude.has( space->intersection_query_results[i]->get_self()))
@@ -135,7 +135,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2& p_from, const Vec
}
-int Physics2DDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude,uint32_t p_user_mask,uint32_t p_object_type_mask) {
+int Physics2DDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
if (p_result_max<=0)
return 0;
@@ -153,7 +153,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Matri
for(int i=0;i<amount;i++) {
- if (!_match_object_type_query(space->intersection_query_results[i],p_user_mask,p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
continue;
if (p_exclude.has( space->intersection_query_results[i]->get_self()))
@@ -182,7 +182,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Matri
-bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude,uint32_t p_user_mask,uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
@@ -204,7 +204,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32
for(int i=0;i<amount;i++) {
- if (!_match_object_type_query(space->intersection_query_results[i],p_user_mask,p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
continue;
if (p_exclude.has( space->intersection_query_results[i]->get_self()))
@@ -267,7 +267,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32
}
-bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,Vector2 *r_results,int p_result_max,int &r_result_count, const Set<RID>& p_exclude,uint32_t p_user_mask,uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,Vector2 *r_results,int p_result_max,int &r_result_count, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
if (p_result_max<=0)
@@ -301,7 +301,7 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Matrix32& p_s
for(int i=0;i<amount;i++) {
- if (!_match_object_type_query(space->intersection_query_results[i],p_user_mask,p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
continue;
const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
@@ -353,7 +353,7 @@ static void _rest_cbk_result(const Vector2& p_point_A,const Vector2& p_point_B,v
}
-bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,ShapeRestInfo *r_info, const Set<RID>& p_exclude,uint32_t p_user_mask,uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,ShapeRestInfo *r_info, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape);
@@ -373,7 +373,7 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Matrix32& p_shape
for(int i=0;i<amount;i++) {
- if (!_match_object_type_query(space->intersection_query_results[i],p_user_mask,p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
continue;
const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index 9d3dfae9b5..bd41097fba 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -46,11 +46,11 @@ public:
Space2DSW *space;
- virtual bool intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
- virtual int intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
- virtual bool cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
- virtual bool collide_shape(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,Vector2 *r_results,int p_result_max,int &r_result_count, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
- virtual bool rest_info(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,ShapeRestInfo *r_info, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
+ virtual bool intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
+ virtual int intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
+ virtual bool cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
+ virtual bool collide_shape(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,Vector2 *r_results,int p_result_max,int &r_result_count, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
+ virtual bool rest_info(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,ShapeRestInfo *r_info, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
Physics2DDirectSpaceStateSW();
};
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index 0851ad59ef..9cbd7414bd 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -329,8 +329,12 @@ void Physics2DServer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("body_get_continuous_collision_detection_mode","body"),&Physics2DServer::body_get_continuous_collision_detection_mode);
- //ObjectTypeDB::bind_method(_MD("body_set_user_flags","flags""),&Physics2DServer::body_set_shape,DEFVAL(Matrix32));
- //ObjectTypeDB::bind_method(_MD("body_get_user_flags","body","shape_idx","shape"),&Physics2DServer::body_get_shape);
+ ObjectTypeDB::bind_method(_MD("body_set_layer_mask","body","mask"),&Physics2DServer::body_set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("body_get_layer_mask","body"),&Physics2DServer::body_get_layer_mask);
+
+ ObjectTypeDB::bind_method(_MD("body_set_user_mask","body","mask"),&Physics2DServer::body_set_user_mask);
+ ObjectTypeDB::bind_method(_MD("body_get_user_mask","body"),&Physics2DServer::body_get_user_mask);
+
ObjectTypeDB::bind_method(_MD("body_set_param","body","param","value"),&Physics2DServer::body_set_param);
ObjectTypeDB::bind_method(_MD("body_get_param","body","param"),&Physics2DServer::body_get_param);
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 172fa1699b..def1e69992 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -88,9 +88,9 @@ class Physics2DDirectSpaceState : public Object {
OBJ_TYPE( Physics2DDirectSpaceState, Object );
- Variant _intersect_ray(const Vector2& p_from, const Vector2& p_to,const Vector<RID>& p_exclude=Vector<RID>(),uint32_t p_user_mask=0);
- Variant _intersect_shape(const RID& p_shape, const Matrix32& p_xform,int p_result_max=64,const Vector<RID>& p_exclude=Vector<RID>(),uint32_t p_user_mask=0);
- Variant _cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,const Vector<RID>& p_exclude=Vector<RID>(),uint32_t p_user_mask=0);
+ Variant _intersect_ray(const Vector2& p_from, const Vector2& p_to,const Vector<RID>& p_exclude=Vector<RID>(),uint32_t p_layers=0);
+ Variant _intersect_shape(const RID& p_shape, const Matrix32& p_xform,int p_result_max=64,const Vector<RID>& p_exclude=Vector<RID>(),uint32_t p_layers=0);
+ Variant _cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,const Vector<RID>& p_exclude=Vector<RID>(),uint32_t p_layers=0);
protected:
@@ -118,7 +118,7 @@ public:
int shape;
};
- virtual bool intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
+ virtual bool intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
struct ShapeResult {
@@ -129,13 +129,13 @@ public:
};
- virtual int intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
+ virtual int intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
- virtual bool cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
+ virtual bool cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
- virtual bool collide_shape(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,Vector2 *r_results,int p_result_max,int &r_result_count, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
+ virtual bool collide_shape(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,Vector2 *r_results,int p_result_max,int &r_result_count, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
struct ShapeRestInfo {
@@ -148,7 +148,7 @@ public:
};
- virtual bool rest_info(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,ShapeRestInfo *r_info, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_user_mask=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
+ virtual bool rest_info(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,ShapeRestInfo *r_info, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
Physics2DDirectSpaceState();
@@ -338,6 +338,9 @@ public:
virtual void body_set_continuous_collision_detection_mode(RID p_body,CCDMode p_mode)=0;
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const=0;
+ virtual void body_set_layer_mask(RID p_body, uint32_t p_mask)=0;
+ virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const=0;
+
virtual void body_set_user_mask(RID p_body, uint32_t p_mask)=0;
virtual uint32_t body_get_user_mask(RID p_body, uint32_t p_mask) const=0;
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index f1b4627b6c..69c82519dd 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -315,6 +315,9 @@ void PhysicsServer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("body_apply_impulse","body","pos","impulse"),&PhysicsServer::body_apply_impulse);
ObjectTypeDB::bind_method(_MD("body_set_axis_velocity","body","axis_velocity"),&PhysicsServer::body_set_axis_velocity);
+ ObjectTypeDB::bind_method(_MD("body_set_axis_lock","body","axis"),&PhysicsServer::body_set_axis_lock);
+ ObjectTypeDB::bind_method(_MD("body_get_axis_lock","body"),&PhysicsServer::body_set_axis_lock);
+
ObjectTypeDB::bind_method(_MD("body_add_collision_exception","body","excepted_body"),&PhysicsServer::body_add_collision_exception);
ObjectTypeDB::bind_method(_MD("body_remove_collision_exception","body","excepted_body"),&PhysicsServer::body_remove_collision_exception);
// virtual void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions)=0;
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 4276a4dab8..da51dbc8e1 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -341,6 +341,16 @@ public:
virtual void body_apply_impulse(RID p_body, const Vector3& p_pos, const Vector3& p_impulse)=0;
virtual void body_set_axis_velocity(RID p_body, const Vector3& p_axis_velocity)=0;
+ enum BodyAxisLock {
+ BODY_AXIS_LOCK_DISABLED,
+ BODY_AXIS_LOCK_X,
+ BODY_AXIS_LOCK_Y,
+ BODY_AXIS_LOCK_Z,
+ };
+
+ virtual void body_set_axis_lock(RID p_body,BodyAxisLock p_lock)=0;
+ virtual BodyAxisLock body_get_axis_lock(RID p_body) const=0;
+
//fix
virtual void body_add_collision_exception(RID p_body, RID p_body_b)=0;
virtual void body_remove_collision_exception(RID p_body, RID p_body_b)=0;
@@ -420,6 +430,7 @@ VARIANT_ENUM_CAST( PhysicsServer::AreaSpaceOverrideMode );
VARIANT_ENUM_CAST( PhysicsServer::BodyMode );
VARIANT_ENUM_CAST( PhysicsServer::BodyParameter );
VARIANT_ENUM_CAST( PhysicsServer::BodyState );
+VARIANT_ENUM_CAST( PhysicsServer::BodyAxisLock );
//VARIANT_ENUM_CAST( PhysicsServer::JointParam );
//VARIANT_ENUM_CAST( PhysicsServer::JointType );
//VARIANT_ENUM_CAST( PhysicsServer::DampedStringParam );
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 4bf2ecab68..1e540a6753 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -682,6 +682,7 @@ public:
virtual Variant environment_get_background_param(RID p_env,EnvironmentBGParam p_param) const=0;
enum EnvironmentFx {
+ ENV_FX_FXAA,
ENV_FX_GLOW,
ENV_FX_DOF_BLUR,
ENV_FX_HDR,
@@ -815,6 +816,7 @@ public:
INSTANCE_FLAG_RECEIVE_SHADOWS,
INSTANCE_FLAG_DEPH_SCALE,
INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
+ INSTANCE_FLAG_USE_BAKED_LIGHT_VOLUME,
INSTANCE_FLAG_MAX
};
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index fc644e76c5..9821dad872 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -85,12 +85,15 @@
#include "plugins/animation_tree_editor_plugin.h"
#include "plugins/tile_set_editor_plugin.h"
#include "plugins/animation_player_editor_plugin.h"
+#include "plugins/baked_light_editor_plugin.h"
// end
#include "tools/editor/io_plugins/editor_texture_import_plugin.h"
#include "tools/editor/io_plugins/editor_scene_import_plugin.h"
#include "tools/editor/io_plugins/editor_font_import_plugin.h"
#include "tools/editor/io_plugins/editor_sample_import_plugin.h"
#include "tools/editor/io_plugins/editor_translation_import_plugin.h"
+#include "tools/editor/io_plugins/editor_mesh_import_plugin.h"
+
EditorNode *EditorNode::singleton=NULL;
@@ -4013,6 +4016,7 @@ EditorNode::EditorNode() {
_scene_import->add_importer(_collada_import);
editor_import_export->add_import_plugin( _scene_import);
editor_import_export->add_import_plugin( Ref<EditorSceneAnimationImportPlugin>( memnew(EditorSceneAnimationImportPlugin(this))));
+ editor_import_export->add_import_plugin( Ref<EditorMeshImportPlugin>( memnew(EditorMeshImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorFontImportPlugin>( memnew(EditorFontImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorSampleImportPlugin>( memnew(EditorSampleImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorTranslationImportPlugin>( memnew(EditorTranslationImportPlugin(this))));
@@ -4051,6 +4055,7 @@ EditorNode::EditorNode() {
add_editor_plugin( memnew( Particles2DEditorPlugin(this) ) );
add_editor_plugin( memnew( Path2DEditorPlugin(this) ) );
add_editor_plugin( memnew( PathEditorPlugin(this) ) );
+ add_editor_plugin( memnew( BakedLightEditorPlugin(this) ) );
for(int i=0;i<EditorPlugins::get_plugin_count();i++)
add_editor_plugin( EditorPlugins::create(i,this) );
diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp
new file mode 100644
index 0000000000..d76a778433
--- /dev/null
+++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp
@@ -0,0 +1,555 @@
+#include "editor_mesh_import_plugin.h"
+
+#include "scene/gui/file_dialog.h"
+#include "tools/editor/editor_dir_dialog.h"
+#include "tools/editor/editor_node.h"
+#include "tools/editor/property_editor.h"
+#include "scene/resources/sample.h"
+#include "io/resource_saver.h"
+#include "os/file_access.h"
+#include "io/marshalls.h"
+#include "scene/resources/surface_tool.h"
+
+class _EditorMeshImportOptions : public Object {
+
+ OBJ_TYPE(_EditorMeshImportOptions,Object);
+public:
+
+
+ bool generate_tangents;
+ bool generate_normals;
+ bool flip_faces;
+ bool smooth_shading;
+ bool weld_vertices;
+ bool import_material;
+ bool import_textures;
+ float weld_tolerance;
+
+
+ bool _set(const StringName& p_name, const Variant& p_value) {
+
+ String n = p_name;
+ if (n=="generate/tangents")
+ generate_tangents=p_value;
+ else if (n=="generate/normals")
+ generate_normals=p_value;
+ else if (n=="import/materials")
+ import_material=p_value;
+ else if (n=="import/textures")
+ import_textures=p_value;
+ else if (n=="force/flip_faces")
+ flip_faces=p_value;
+ else if (n=="force/smooth_shading")
+ smooth_shading=p_value;
+ else if (n=="force/weld_vertices")
+ weld_vertices=p_value;
+ else if (n=="force/weld_tolerance")
+ weld_tolerance=p_value;
+ else
+ return false;
+
+ return true;
+
+ }
+
+ bool _get(const StringName& p_name,Variant &r_ret) const{
+
+ String n = p_name;
+ if (n=="generate/tangents")
+ r_ret=generate_tangents;
+ else if (n=="generate/normals")
+ r_ret=generate_normals;
+ else if (n=="import/materials")
+ r_ret=import_material;
+ else if (n=="import/textures")
+ r_ret=import_textures;
+ else if (n=="force/flip_faces")
+ r_ret=flip_faces;
+ else if (n=="force/smooth_shading")
+ r_ret=smooth_shading;
+ else if (n=="force/weld_vertices")
+ r_ret=weld_vertices;
+ else if (n=="force/weld_tolerance")
+ r_ret=weld_tolerance;
+ else
+ return false;
+
+ return true;
+
+ }
+ void _get_property_list( List<PropertyInfo> *p_list) const{
+
+ p_list->push_back(PropertyInfo(Variant::BOOL,"generate/tangents"));
+ p_list->push_back(PropertyInfo(Variant::BOOL,"generate/normals"));
+ //not for nowp
+ //p_list->push_back(PropertyInfo(Variant::BOOL,"import/materials"));
+ //p_list->push_back(PropertyInfo(Variant::BOOL,"import/textures"));
+ p_list->push_back(PropertyInfo(Variant::BOOL,"force/flip_faces"));
+ p_list->push_back(PropertyInfo(Variant::BOOL,"force/smooth_shading"));
+ p_list->push_back(PropertyInfo(Variant::BOOL,"force/weld_vertices"));
+ p_list->push_back(PropertyInfo(Variant::REAL,"force/weld_tolerance",PROPERTY_HINT_RANGE,"0.00001,16,0.00001"));
+ //p_list->push_back(PropertyInfo(Variant::BOOL,"compress/enable"));
+ //p_list->push_back(PropertyInfo(Variant::INT,"compress/bitrate",PROPERTY_HINT_ENUM,"64,96,128,192"));
+
+
+ }
+
+
+ static void _bind_methods() {
+
+
+ ADD_SIGNAL( MethodInfo("changed"));
+ }
+
+
+ _EditorMeshImportOptions() {
+
+ generate_tangents=true;
+ generate_normals=true;
+ flip_faces=false;
+ smooth_shading=false;
+ weld_vertices=true;
+ weld_tolerance=0.0001;
+ import_material=false;
+ import_textures=false;
+
+ }
+
+
+};
+
+class EditorMeshImportDialog : public ConfirmationDialog {
+
+ OBJ_TYPE(EditorMeshImportDialog,ConfirmationDialog);
+
+ EditorMeshImportPlugin *plugin;
+
+ LineEdit *import_path;
+ LineEdit *save_path;
+ FileDialog *file_select;
+ EditorDirDialog *save_select;
+ ConfirmationDialog *error_dialog;
+ PropertyEditor *option_editor;
+
+ _EditorMeshImportOptions *options;
+
+
+public:
+
+ void _choose_files(const Vector<String>& p_path) {
+
+ String files;
+ for(int i=0;i<p_path.size();i++) {
+
+ if (i>0)
+ files+=",";
+ files+=p_path[i];
+ }
+ /*
+ if (p_path.size()) {
+ String srctex=p_path[0];
+ String ipath = EditorImportDB::get_singleton()->find_source_path(srctex);
+
+ if (ipath!="")
+ save_path->set_text(ipath.get_base_dir());
+ }*/
+ import_path->set_text(files);
+
+ }
+ void _choose_save_dir(const String& p_path) {
+
+ save_path->set_text(p_path);
+ }
+
+ void _browse() {
+
+ file_select->popup_centered_ratio();
+ }
+
+ void _browse_target() {
+
+ save_select->popup_centered_ratio();
+
+ }
+
+
+ void popup_import(const String& p_path) {
+
+ popup_centered(Size2(400,400));
+ if (p_path!="") {
+
+ Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path);
+ ERR_FAIL_COND(!rimd.is_valid());
+
+ save_path->set_text(p_path.get_base_dir());
+ List<String> opts;
+ rimd->get_options(&opts);
+ for(List<String>::Element *E=opts.front();E;E=E->next()) {
+
+ options->_set(E->get(),rimd->get_option(E->get()));
+ }
+
+ String src = "";
+ for(int i=0;i<rimd->get_source_count();i++) {
+ if (i>0)
+ src+=",";
+ src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i));
+ }
+ import_path->set_text(src);
+ }
+ }
+
+
+ void _import() {
+
+ Vector<String> meshes = import_path->get_text().split(",");
+
+ if (meshes.size()==0) {
+ error_dialog->set_text("No meshes to import!");
+ error_dialog->popup_centered(Size2(200,100));
+ }
+
+ for(int i=0;i<meshes.size();i++) {
+
+ Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata );
+
+ List<PropertyInfo> pl;
+ options->_get_property_list(&pl);
+ for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
+
+ Variant v;
+ String opt=E->get().name;
+ options->_get(opt,v);
+ imd->set_option(opt,v);
+
+ }
+
+ imd->add_source(EditorImportPlugin::validate_source_path(meshes[i]));
+
+ String dst = save_path->get_text();
+ if (dst=="") {
+ error_dialog->set_text("Save path is empty!");
+ error_dialog->popup_centered(Size2(200,100));
+ }
+
+ dst = dst.plus_file(meshes[i].get_file().basename()+".msh");
+
+ Error err = plugin->import(dst,imd);
+ }
+
+ hide();
+
+ }
+
+
+ void _notification(int p_what) {
+
+
+ if (p_what==NOTIFICATION_ENTER_SCENE) {
+
+ option_editor->edit(options);
+ }
+ }
+
+ static void _bind_methods() {
+
+
+ ObjectTypeDB::bind_method("_choose_files",&EditorMeshImportDialog::_choose_files);
+ ObjectTypeDB::bind_method("_choose_save_dir",&EditorMeshImportDialog::_choose_save_dir);
+ ObjectTypeDB::bind_method("_import",&EditorMeshImportDialog::_import);
+ ObjectTypeDB::bind_method("_browse",&EditorMeshImportDialog::_browse);
+ ObjectTypeDB::bind_method("_browse_target",&EditorMeshImportDialog::_browse_target);
+ // ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) );
+ }
+
+ EditorMeshImportDialog(EditorMeshImportPlugin *p_plugin) {
+
+ plugin=p_plugin;
+
+
+ set_title("Single Mesh Import");
+
+ VBoxContainer *vbc = memnew( VBoxContainer );
+ add_child(vbc);
+ set_child_rect(vbc);
+
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ vbc->add_margin_child("Source Mesh(es):",hbc);
+
+ import_path = memnew( LineEdit );
+ import_path->set_h_size_flags(SIZE_EXPAND_FILL);
+ hbc->add_child(import_path);
+
+ Button * import_choose = memnew( Button );
+ import_choose->set_text(" .. ");
+ hbc->add_child(import_choose);
+
+ import_choose->connect("pressed", this,"_browse");
+
+ hbc = memnew( HBoxContainer );
+ vbc->add_margin_child("Target Path:",hbc);
+
+ save_path = memnew( LineEdit );
+ save_path->set_h_size_flags(SIZE_EXPAND_FILL);
+ hbc->add_child(save_path);
+
+ Button * save_choose = memnew( Button );
+ save_choose->set_text(" .. ");
+ hbc->add_child(save_choose);
+
+ save_choose->connect("pressed", this,"_browse_target");
+
+ file_select = memnew(FileDialog);
+ file_select->set_access(FileDialog::ACCESS_FILESYSTEM);
+ add_child(file_select);
+ file_select->set_mode(FileDialog::MODE_OPEN_FILES);
+ file_select->connect("files_selected", this,"_choose_files");
+ file_select->add_filter("*.obj ; Wavefront OBJ");
+ save_select = memnew( EditorDirDialog );
+ add_child(save_select);
+
+ // save_select->set_mode(FileDialog::MODE_OPEN_DIR);
+ save_select->connect("dir_selected", this,"_choose_save_dir");
+
+ get_ok()->connect("pressed", this,"_import");
+ get_ok()->set_text("Import");
+
+
+ error_dialog = memnew ( ConfirmationDialog );
+ add_child(error_dialog);
+ error_dialog->get_ok()->set_text("Accept");
+ // error_dialog->get_cancel()->hide();
+
+ set_hide_on_ok(false);
+ options = memnew( _EditorMeshImportOptions );
+
+ option_editor = memnew( PropertyEditor );
+ option_editor->hide_top_label();
+ vbc->add_margin_child("Options:",option_editor,true);
+ }
+
+ ~EditorMeshImportDialog() {
+ memdelete(options);
+ }
+
+};
+
+
+String EditorMeshImportPlugin::get_name() const {
+
+ return "mesh";
+}
+String EditorMeshImportPlugin::get_visible_name() const{
+
+ return "3D Mesh";
+}
+void EditorMeshImportPlugin::import_dialog(const String& p_from){
+
+ dialog->popup_import(p_from);
+}
+Error EditorMeshImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){
+
+
+ ERR_FAIL_COND_V(p_from->get_source_count()!=1,ERR_INVALID_PARAMETER);
+
+ Ref<ResourceImportMetadata> from=p_from;
+
+ String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0));
+ FileAccessRef f = FileAccess::open(src_path,FileAccess::READ);
+ ERR_FAIL_COND_V(!f,ERR_CANT_OPEN);
+
+ Ref<Mesh> mesh;
+ Map<String,Ref<Material> > name_map;
+
+ if (FileAccess::exists(p_path)) {
+ mesh=ResourceLoader::load(p_path,"Mesh");
+ if (mesh.is_valid()) {
+ for(int i=0;i<mesh->get_surface_count();i++) {
+
+ if (!mesh->surface_get_material(i).is_valid())
+ continue;
+ String name;
+ if (mesh->surface_get_name(i)!="")
+ name=mesh->surface_get_name(i);
+ else
+ name="Surface "+itos(i+1);
+
+ name_map[name]=mesh->surface_get_material(i);
+ }
+
+ while(mesh->get_surface_count()) {
+ mesh->surface_remove(0);
+ }
+ }
+ }
+
+ if (!mesh.is_valid())
+ mesh = Ref<Mesh>( memnew( Mesh ) );
+
+
+ bool generate_normals=from->get_option("generate/normals");
+ bool generate_tangents=from->get_option("generate/tangents");
+ bool flip_faces=from->get_option("force/flip_faces");
+ bool force_smooth=from->get_option("force/smooth_shading");
+ bool weld_vertices=from->get_option("force/weld_vertices");
+ float weld_tolerance=from->get_option("force/weld_tolerance");
+ Vector<Vector3> vertices;
+ Vector<Vector3> normals;
+ Vector<Vector2> uvs;
+ String name;
+
+ Ref<SurfaceTool> surf_tool = memnew( SurfaceTool) ;
+ surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
+ if (force_smooth)
+ surf_tool->add_smooth_group(true);
+ int has_index_data=false;
+
+ while(true) {
+
+
+ String l = f->get_line().strip_edges();
+
+ if (l.begins_with("v ")) {
+ //vertex
+ Vector<String> v = l.split(" ",false);
+ ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA);
+ Vector3 vtx;
+ vtx.x=v[1].to_float();
+ vtx.y=v[2].to_float();
+ vtx.z=v[3].to_float();
+ vertices.push_back(vtx);
+ } else if (l.begins_with("vt ")) {
+ //uv
+ Vector<String> v = l.split(" ",false);
+ ERR_FAIL_COND_V(v.size()<3,ERR_INVALID_DATA);
+ Vector2 uv;
+ uv.x=v[1].to_float();
+ uv.y=v[2].to_float();
+ uvs.push_back(uv);
+
+ } else if (l.begins_with("vn ")) {
+ //normal
+ Vector<String> v = l.split(" ",false);
+ ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA);
+ Vector3 nrm;
+ nrm.x=v[1].to_float();
+ nrm.y=v[2].to_float();
+ nrm.z=v[3].to_float();
+ normals.push_back(nrm);
+ } if (l.begins_with("f ")) {
+ //vertex
+
+ has_index_data=true;
+ Vector<String> v = l.split(" ",false);
+ ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA);
+
+ //not very fast, could be sped up
+
+
+ Vector<String> face[3];
+ face[0] = v[1].split("/");
+ face[1] = v[2].split("/");
+ ERR_FAIL_COND_V(face[0].size()==0,ERR_PARSE_ERROR);
+ ERR_FAIL_COND_V(face[0].size()!=face[1].size(),ERR_PARSE_ERROR);
+ for(int i=2;i<v.size()-1;i++) {
+
+ face[2] = v[i+1].split("/");
+ ERR_FAIL_COND_V(face[0].size()!=face[2].size(),ERR_PARSE_ERROR);
+ for(int j=0;j<3;j++) {
+
+ int idx=j;
+
+ if (!flip_faces && idx<2) {
+ idx=1^idx;
+ }
+
+
+ if (face[idx].size()==3) {
+ int norm = face[idx][2].to_int()-1;
+ ERR_FAIL_INDEX_V(norm,normals.size(),ERR_PARSE_ERROR);
+ surf_tool->add_normal(normals[norm]);
+ }
+
+ if (face[idx].size()>=2 && face[idx][1]!=String()) {
+
+ int uv = face[idx][1].to_int()-1;
+ ERR_FAIL_INDEX_V(uv,uvs.size(),ERR_PARSE_ERROR);
+ surf_tool->add_uv(uvs[uv]);
+ }
+
+ int vtx = face[idx][0].to_int()-1;
+ print_line("vtx: "+itos(vtx)+"/"+itos(vertices.size()));
+ ERR_FAIL_INDEX_V(vtx,vertices.size(),ERR_PARSE_ERROR);
+
+ Vector3 vertex = vertices[vtx];
+ if (weld_vertices)
+ vertex=vertex.snapped(weld_tolerance);
+ surf_tool->add_vertex(vertex);
+ }
+
+ face[1]=face[2];
+ }
+ } else if (l.begins_with("s ") && !force_smooth) { //smoothing
+ String what = l.substr(2,l.length()).strip_edges();
+ if (what=="off")
+ surf_tool->add_smooth_group(false);
+ else
+ surf_tool->add_smooth_group(true);
+
+ } else if (l.begins_with("o ") || f->eof_reached()) { //new surface or done
+
+ if (has_index_data) {
+ //new object/surface
+ if (generate_normals || force_smooth)
+ surf_tool->generate_normals();
+ if (uvs.size() && (normals.size() || generate_normals))
+ surf_tool->generate_tangents();
+
+ surf_tool->index();
+ mesh = surf_tool->commit(mesh);
+ if (name=="")
+ name="Surface "+itos(mesh->get_surface_count()-1);
+ mesh->surface_set_name(mesh->get_surface_count()-1,name);
+ name="";
+ surf_tool->clear();
+ surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
+ if (force_smooth)
+ surf_tool->add_smooth_group(true);
+
+ has_index_data=false;
+
+ if (f->eof_reached())
+ break;
+ }
+
+ if (l.begins_with("o ")) //name
+ name=l.substr(2,l.length()).strip_edges();
+ }
+ }
+
+
+ from->set_source_md5(0,FileAccess::get_md5(src_path));
+ from->set_editor(get_name());
+ mesh->set_import_metadata(from);
+
+ //re-apply materials if exist
+ for(int i=0;i<mesh->get_surface_count();i++) {
+
+ String n = mesh->surface_get_name(i);
+ if (name_map.has(n))
+ mesh->surface_set_material(i,name_map[n]);
+ }
+
+ Error err = ResourceSaver::save(p_path,mesh);
+
+ return err;
+}
+
+
+EditorMeshImportPlugin::EditorMeshImportPlugin(EditorNode* p_editor) {
+
+ dialog = memnew( EditorMeshImportDialog(this));
+ p_editor->get_gui_base()->add_child(dialog);
+}
+
diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.h b/tools/editor/io_plugins/editor_mesh_import_plugin.h
new file mode 100644
index 0000000000..014954685d
--- /dev/null
+++ b/tools/editor/io_plugins/editor_mesh_import_plugin.h
@@ -0,0 +1,29 @@
+#ifndef EDITOR_MESH_IMPORT_PLUGIN_H
+#define EDITOR_MESH_IMPORT_PLUGIN_H
+
+
+#include "tools/editor/editor_import_export.h"
+#include "scene/resources/font.h"
+
+class EditorNode;
+class EditorMeshImportDialog;
+
+class EditorMeshImportPlugin : public EditorImportPlugin {
+
+ OBJ_TYPE(EditorMeshImportPlugin,EditorImportPlugin);
+
+ EditorMeshImportDialog *dialog;
+
+
+public:
+
+ virtual String get_name() const;
+ virtual String get_visible_name() const;
+ virtual void import_dialog(const String& p_from="");
+ virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from);
+
+
+ EditorMeshImportPlugin(EditorNode* p_editor);
+};
+
+#endif // EDITOR_MESH_IMPORT_PLUGIN_H
diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp
index 55cba432e3..cd02156eef 100644
--- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_sample_import_plugin.cpp
@@ -41,6 +41,12 @@ class _EditorSampleImportOptions : public Object {
OBJ_TYPE(_EditorSampleImportOptions,Object);
public:
+ enum CompressMode {
+ COMPRESS_MODE_DISABLED,
+ COMPRESS_MODE_RAM,
+ COMPRESS_MODE_DISK
+ };
+
enum CompressBitrate {
COMPRESS_64,
COMPRESS_96,
@@ -57,7 +63,7 @@ public:
bool edit_normalize;
bool edit_loop;
- bool compress_enable;
+ CompressMode compress_mode;
CompressBitrate compress_bitrate;
@@ -78,8 +84,8 @@ public:
edit_normalize=p_value;
else if (n=="edit/loop")
edit_loop=p_value;
- else if (n=="compress/enable")
- compress_enable=p_value;
+ else if (n=="compress/mode")
+ compress_mode=CompressMode(int(p_value));
else if (n=="compress/bitrate")
compress_bitrate=CompressBitrate(int(p_value));
else
@@ -106,8 +112,8 @@ public:
r_ret=edit_normalize;
else if (n=="edit/loop")
r_ret=edit_loop;
- else if (n=="compress/enable")
- r_ret=compress_enable;
+ else if (n=="compress/mode")
+ r_ret=compress_mode;
else if (n=="compress/bitrate")
r_ret=compress_bitrate;
else
@@ -125,7 +131,7 @@ public:
p_list->push_back(PropertyInfo(Variant::BOOL,"edit/trim"));
p_list->push_back(PropertyInfo(Variant::BOOL,"edit/normalize"));
p_list->push_back(PropertyInfo(Variant::BOOL,"edit/loop"));
- //p_list->push_back(PropertyInfo(Variant::BOOL,"compress/enable"));
+ p_list->push_back(PropertyInfo(Variant::INT,"compress/mode",PROPERTY_HINT_ENUM,"Disabled,RAM (Ima-ADPCM)"));
//p_list->push_back(PropertyInfo(Variant::INT,"compress/bitrate",PROPERTY_HINT_ENUM,"64,96,128,192"));
@@ -150,7 +156,7 @@ public:
edit_normalize=true;
edit_loop=false;
- compress_enable=false;
+ compress_mode=COMPRESS_MODE_DISABLED;
compress_bitrate=COMPRESS_128;
}
@@ -554,7 +560,11 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI
loop_end=len;
}
+ int compression = from->get_option("compress/mode");
bool force_mono = from->get_option("force/mono");
+ if (compression==_EditorSampleImportOptions::COMPRESS_MODE_RAM)
+ force_mono=true;
+
if (force_mono && chans==2) {
Vector<float> new_data;
@@ -575,19 +585,31 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI
DVector<uint8_t> dst_data;
- dst_data.resize( data.size() * (is16?2:1));
- {
- DVector<uint8_t>::Write w = dst_data.write();
+ Sample::Format dst_format;
- int ds=data.size();
- for(int i=0;i<ds;i++) {
+ if ( compression == _EditorSampleImportOptions::COMPRESS_MODE_RAM) {
- if (is16) {
- int16_t v = CLAMP(data[i]*32767,-32768,32767);
- encode_uint16(v,&w[i*2]);
- } else {
- int8_t v = CLAMP(data[i]*127,-128,127);
- w[i]=v;
+ dst_format=Sample::FORMAT_IMA_ADPCM;
+
+ _compress_ima_adpcm(data,dst_data);
+
+ } else {
+
+ dst_format=is16?Sample::FORMAT_PCM16:Sample::FORMAT_PCM8;
+ dst_data.resize( data.size() * (is16?2:1));
+ {
+ DVector<uint8_t>::Write w = dst_data.write();
+
+ int ds=data.size();
+ for(int i=0;i<ds;i++) {
+
+ if (is16) {
+ int16_t v = CLAMP(data[i]*32767,-32768,32767);
+ encode_uint16(v,&w[i*2]);
+ } else {
+ int8_t v = CLAMP(data[i]*127,-128,127);
+ w[i]=v;
+ }
}
}
}
@@ -603,7 +625,7 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI
target = smp;
}
- target->create(is16?Sample::FORMAT_PCM16:Sample::FORMAT_PCM8,chans==2?true:false,len);
+ target->create(dst_format,chans==2?true:false,len);
target->set_data(dst_data);
target->set_mix_rate(rate);
target->set_loop_format(loop);
@@ -621,6 +643,124 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI
}
+void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,DVector<uint8_t>& dst_data) {
+
+
+ /*p_sample_data->data = (void*)malloc(len);
+ xm_s8 *dataptr=(xm_s8*)p_sample_data->data;*/
+
+ static const int16_t _ima_adpcm_step_table[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+ };
+
+ static const int8_t _ima_adpcm_index_table[16] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+ };
+
+
+ int datalen = p_data.size();
+ int datamax=datalen;
+ if (datalen&1)
+ datalen++;
+
+ dst_data.resize(datalen/2+4);
+ DVector<uint8_t>::Write w = dst_data.write();
+
+
+ int i,step_idx=0,prev=0;
+ uint8_t *out = w.ptr();
+ //int16_t xm_prev=0;
+ const float *in=p_data.ptr();
+
+
+ /* initial value is zero */
+ *(out++) =0;
+ *(out++) =0;
+ /* Table index initial value */
+ *(out++) =0;
+ /* unused */
+ *(out++) =0;
+
+ for (i=0;i<datalen;i++) {
+ int step,diff,vpdiff,signed_nibble,p,mask;
+ uint8_t nibble;
+ int16_t xm_sample;
+
+ if (i>=datamax)
+ xm_sample=0;
+ else {
+
+
+ xm_sample=CLAMP(in[i]*32767.0,-32768,32767);
+ if (xm_sample==32767 || xm_sample==-32768)
+ printf("clippy!\n",xm_sample);
+ }
+
+ // xm_sample=xm_sample+xm_prev;
+ // xm_prev=xm_sample;
+
+ diff = (int)xm_sample - prev ;
+
+ nibble=0 ;
+ step = _ima_adpcm_step_table[ step_idx ];
+ vpdiff = step >> 3 ;
+ if (diff < 0) {
+ nibble=8;
+ diff=-diff ;
+ }
+ mask = 4 ;
+ while (mask) {
+
+ if (diff >= step) {
+
+ nibble |= mask;
+ diff -= step;
+ vpdiff += step;
+ }
+
+ step >>= 1 ;
+ mask >>= 1 ;
+ };
+
+ if (nibble&8)
+ prev-=vpdiff ;
+ else
+ prev+=vpdiff ;
+
+ if (prev > 32767) {
+ printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev);
+ prev=32767;
+ } else if (prev < -32768) {
+ printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev);
+ prev = -32768 ;
+ }
+
+ step_idx += _ima_adpcm_index_table[nibble];
+ if (step_idx< 0)
+ step_idx= 0 ;
+ else if (step_idx> 88)
+ step_idx= 88 ;
+
+
+ if (i&1) {
+ *out|=nibble<<4;
+ out++;
+ } else {
+ *out=nibble;
+ }
+ /*dataptr[i]=prev>>8;*/
+ }
+
+}
EditorSampleImportPlugin::EditorSampleImportPlugin(EditorNode* p_editor) {
diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.h b/tools/editor/io_plugins/editor_sample_import_plugin.h
index a5420671e6..176dece0d5 100644
--- a/tools/editor/io_plugins/editor_sample_import_plugin.h
+++ b/tools/editor/io_plugins/editor_sample_import_plugin.h
@@ -40,6 +40,7 @@ class EditorSampleImportPlugin : public EditorImportPlugin {
OBJ_TYPE(EditorSampleImportPlugin,EditorImportPlugin);
EditorSampleImportDialog *dialog;
+ void _compress_ima_adpcm(const Vector<float>& p_data,DVector<uint8_t>& dst_data);
public:
virtual String get_name() const;
diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/tools/editor/plugins/baked_light_editor_plugin.cpp
new file mode 100644
index 0000000000..b1e42e3369
--- /dev/null
+++ b/tools/editor/plugins/baked_light_editor_plugin.cpp
@@ -0,0 +1,996 @@
+#include "baked_light_editor_plugin.h"
+#include "scene/gui/box_container.h"
+#include "scene/3d/mesh_instance.h"
+#include "scene/3d/light.h"
+
+
+class BakedLightBaker {
+public:
+
+ enum {
+
+ ATTENUATION_CURVE_LEN=256
+ };
+
+ struct Octant {
+ bool leaf;
+ union {
+ struct {
+ float light_accum[3];
+ float surface_area;
+ Octant *next_leaf;
+ float offset[3];
+ };
+ Octant* children[8];
+ };
+ };
+
+ struct Triangle {
+
+ Vector3 vertices[3];
+ Vector2 uv[3];
+ };
+
+
+ struct BVH {
+
+ AABB aabb;
+ Vector3 center;
+ Triangle *leaf;
+ BVH*children[2];
+ };
+
+
+ struct BVHCmpX {
+
+ bool operator()(const BVH* p_left, const BVH* p_right) const {
+
+ return p_left->center.x < p_right->center.x;
+ }
+ };
+
+ struct BVHCmpY {
+
+ bool operator()(const BVH* p_left, const BVH* p_right) const {
+
+ return p_left->center.y < p_right->center.y;
+ }
+ };
+ struct BVHCmpZ {
+
+ bool operator()(const BVH* p_left, const BVH* p_right) const {
+
+ return p_left->center.z < p_right->center.z;
+ }
+ };
+
+
+ struct DirLight {
+
+
+ Vector3 pos;
+ Vector3 up;
+ Vector3 left;
+ Vector3 dir;
+ Color diffuse;
+ Color specular;
+ float energy;
+ float length;
+ int rays_thrown;
+
+ };
+
+ AABB octree_aabb;
+ Octant *octree;
+ BVH*bvh;
+ Vector<Triangle> triangles;
+ Transform base_inv;
+ Octant *leaf_list;
+ int octree_depth;
+ int cell_count;
+ uint32_t *ray_stack;
+ BVH **bvh_stack;
+ float cell_size;
+ float plot_size; //multiplied by cell size
+ Vector<DirLight> directional_lights;
+ int max_bounces;
+
+
+
+ void _add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_mat_override,const Transform& p_xform);
+ void _parse_geometry(Node* p_node);
+ BVH* _parse_bvh(BVH** p_children,int p_size,int p_depth,int& max_depth);
+ void _make_bvh();
+ void _make_octree();
+ void _octree_insert(const AABB& p_aabb,Octant *p_octant,Triangle* p_triangle, int p_depth);
+
+ void _free_octree(Octant *p_octant) {
+
+ if (!p_octant->leaf) {
+
+ for(int i=0;i<8;i++) {
+ if (p_octant->children[i])
+ _free_octree(p_octant->children[i]);
+ }
+ }
+
+ memdelete(p_octant);
+ }
+
+ void _free_bvh(BVH* p_bvh) {
+
+ if (!p_bvh->leaf) {
+ if (p_bvh->children[0])
+ _free_bvh(p_bvh->children[0]);
+ if (p_bvh->children[1])
+ _free_bvh(p_bvh->children[1]);
+ }
+
+ memdelete(p_bvh);
+
+ }
+
+ void _fix_lights();
+
+
+ void _plot_light(const Vector3& p_plot_pos,const AABB& p_plot_aabb, Octant *p_octant, const AABB& p_aabb,const Color& p_light);
+ void _throw_ray(const Vector3& p_from, const Vector3& p_to,const Color& p_light,float *p_att_curve,float p_att_curve_len,int p_bounces);
+
+
+ void throw_rays(int p_amount);
+ float get_normalization() const;
+
+
+ void bake(Node *p_base);
+
+
+ void clear() {
+
+ if (octree)
+ _free_octree(octree);
+ if (bvh)
+ _free_bvh(bvh);
+
+ if (ray_stack)
+ memdelete_arr(ray_stack);
+ if (bvh_stack)
+ memdelete_arr(bvh_stack);
+
+ octree=NULL;
+ bvh=NULL;
+ leaf_list=NULL;
+ cell_count=0;
+ ray_stack=NULL;
+ bvh_stack=NULL;
+ }
+
+ BakedLightBaker() {
+ octree_depth=8;
+ octree=NULL;
+ bvh=NULL;
+ leaf_list=NULL;
+ cell_count=0;
+ ray_stack=NULL;
+ bvh_stack=NULL;
+ plot_size=2;
+ max_bounces=3;
+ }
+
+ ~BakedLightBaker() {
+
+ clear();
+ }
+
+};
+
+
+void BakedLightBaker::_add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_mat_override,const Transform& p_xform) {
+
+
+ for(int i=0;i<p_mesh->get_surface_count();i++) {
+
+ if (p_mesh->surface_get_primitive_type(i)!=Mesh::PRIMITIVE_TRIANGLES)
+ continue;
+ Ref<Material> mat = p_mat_override.is_valid()?p_mat_override:p_mesh->surface_get_material(i);
+
+ int facecount=0;
+
+
+ if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_INDEX) {
+
+ facecount=p_mesh->surface_get_array_index_len(i);
+ } else {
+
+ facecount=p_mesh->surface_get_array_len(i);
+ }
+
+ ERR_CONTINUE((facecount==0 || (facecount%3)!=0));
+
+ facecount/=3;
+
+ int tbase=triangles.size();
+ triangles.resize(facecount+tbase);
+
+
+ Array a = p_mesh->surface_get_arrays(i);
+
+ DVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
+ DVector<Vector3>::Read vr=vertices.read();
+
+ if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_INDEX) {
+
+ DVector<int> indices = a[Mesh::ARRAY_INDEX];
+ DVector<int>::Read ir = indices.read();
+
+ for(int i=0;i<facecount;i++) {
+ Triangle &t=triangles[tbase+i];
+ t.vertices[0]=p_xform.xform(vr[ ir[i*3+0] ]);
+ t.vertices[1]=p_xform.xform(vr[ ir[i*3+1] ]);
+ t.vertices[2]=p_xform.xform(vr[ ir[i*3+2] ]);
+ }
+
+ } else {
+
+ for(int i=0;i<facecount;i++) {
+ Triangle &t=triangles[tbase+i];
+ t.vertices[0]=p_xform.xform(vr[ i*3+0 ]);
+ t.vertices[1]=p_xform.xform(vr[ i*3+1 ]);
+ t.vertices[2]=p_xform.xform(vr[ i*3+2 ]);
+ }
+ }
+ }
+
+}
+
+
+void BakedLightBaker::_parse_geometry(Node* p_node) {
+
+ if (p_node->cast_to<MeshInstance>()) {
+
+ MeshInstance *meshi=p_node->cast_to<MeshInstance>();
+ Ref<Mesh> mesh=meshi->get_mesh();
+ if (mesh.is_valid()) {
+ _add_mesh(mesh,meshi->get_material_override(),base_inv * meshi->get_global_transform());
+ }
+ }
+
+ if (p_node->cast_to<DirectionalLight>()) {
+
+ DirectionalLight *dl=p_node->cast_to<DirectionalLight>();
+
+ DirLight dirl;
+ dirl.diffuse=dl->get_color(DirectionalLight::COLOR_DIFFUSE);
+ dirl.specular=dl->get_color(DirectionalLight::COLOR_SPECULAR);
+ dirl.energy=dl->get_parameter(DirectionalLight::PARAM_ENERGY);
+ dirl.pos=dl->get_global_transform().origin;
+ dirl.up=dl->get_global_transform().basis.get_axis(1).normalized();
+ dirl.left=dl->get_global_transform().basis.get_axis(0).normalized();
+ dirl.dir=-dl->get_global_transform().basis.get_axis(2).normalized();
+ dirl.rays_thrown=0;
+ directional_lights.push_back(dirl);
+
+ }
+
+ for(int i=0;i<p_node->get_child_count();i++) {
+
+ _parse_geometry(p_node->get_child(i));
+ }
+}
+
+
+void BakedLightBaker::_fix_lights() {
+
+
+ for(int i=0;i<directional_lights.size();i++) {
+
+ DirLight &dl=directional_lights[i];
+ float up_max=-1e10;
+ float dir_max=-1e10;
+ float left_max=-1e10;
+ float up_min=1e10;
+ float dir_min=1e10;
+ float left_min=1e10;
+
+ for(int j=0;j<triangles.size();j++) {
+
+ for(int k=0;k<3;k++) {
+
+ Vector3 v = triangles[j].vertices[j];
+
+ float up_d = dl.up.dot(v);
+ float dir_d = dl.dir.dot(v);
+ float left_d = dl.left.dot(v);
+
+ if (up_d>up_max)
+ up_max=up_d;
+ if (up_d<up_min)
+ up_min=up_d;
+
+ if (left_d>left_max)
+ left_max=left_d;
+ if (left_d<left_min)
+ left_min=left_d;
+
+ if (dir_d>dir_max)
+ dir_max=dir_d;
+ if (dir_d<dir_min)
+ dir_min=dir_d;
+
+ }
+ }
+
+ //make a center point, then the upvector and leftvector
+ dl.pos = dl.left*( left_max+left_min )*0.5 + dl.up*( up_max+up_min )*0.5 + dl.dir*(dir_min-(dir_max-dir_min));
+ dl.left*=(left_max-left_min)*0.5;
+ dl.up*=(up_max-up_min)*0.5;
+ dl.length = (dir_max - dir_min)*10; //arbitrary number to keep it in scale
+
+ }
+}
+
+BakedLightBaker::BVH* BakedLightBaker::_parse_bvh(BVH** p_children, int p_size, int p_depth, int &max_depth) {
+
+ if (p_depth>max_depth) {
+ max_depth=p_depth;
+ }
+
+ if (p_size==1) {
+
+ return p_children[0];
+ } else if (p_size==0) {
+
+ return NULL;
+ }
+
+
+ AABB aabb;
+ aabb=p_children[0]->aabb;
+ for(int i=1;i<p_size;i++) {
+
+ aabb.merge_with(p_children[i]->aabb);
+ }
+
+ int li=aabb.get_longest_axis_index();
+
+ switch(li) {
+
+ case Vector3::AXIS_X: {
+ SortArray<BVH*,BVHCmpX> sort_x;
+ sort_x.nth_element(0,p_size,p_size/2,p_children);
+ //sort_x.sort(&p_bb[p_from],p_size);
+ } break;
+ case Vector3::AXIS_Y: {
+ SortArray<BVH*,BVHCmpY> sort_y;
+ sort_y.nth_element(0,p_size,p_size/2,p_children);
+ //sort_y.sort(&p_bb[p_from],p_size);
+ } break;
+ case Vector3::AXIS_Z: {
+ SortArray<BVH*,BVHCmpZ> sort_z;
+ sort_z.nth_element(0,p_size,p_size/2,p_children);
+ //sort_z.sort(&p_bb[p_from],p_size);
+
+ } break;
+ }
+
+
+ BVH* left = _parse_bvh(p_children,p_size/2,p_depth+1,max_depth);
+ BVH* right = _parse_bvh(&p_children[p_size/2],p_size-p_size/2,p_depth+1,max_depth);
+
+ BVH *_new = memnew(BVH);
+ _new->aabb=aabb;
+ _new->center=aabb.pos+aabb.size*0.5;
+ _new->children[0]=left;
+ _new->children[1]=right;
+ _new->leaf=NULL;
+
+ return _new;
+}
+
+void BakedLightBaker::_make_bvh() {
+
+ Vector<BVH*> bases;
+ bases.resize(triangles.size());
+ int max_depth=0;
+ for(int i=0;i<triangles.size();i++) {
+ bases[i]=memnew( BVH );
+ bases[i]->leaf=&triangles[i];
+ bases[i]->aabb.pos=triangles[i].vertices[0];
+ bases[i]->aabb.expand_to(triangles[i].vertices[1]);
+ bases[i]->aabb.expand_to(triangles[i].vertices[2]);
+ bases[i]->center=bases[i]->aabb.pos+bases[i]->aabb.size*0.5;
+ }
+
+ bvh=_parse_bvh(bases.ptr(),bases.size(),1,max_depth);
+ ray_stack = memnew_arr(uint32_t,max_depth);
+ bvh_stack = memnew_arr(BVH*,max_depth);
+}
+
+void BakedLightBaker::_octree_insert(const AABB& p_aabb,Octant *p_octant,Triangle* p_triangle, int p_depth) {
+
+ if (p_octant->leaf) {
+
+ if (p_aabb.has_point(p_triangle->vertices[0]) && p_aabb.has_point(p_triangle->vertices[1]) &&p_aabb.has_point(p_triangle->vertices[2])) {
+ //face is completely enclosed, add area
+ p_octant->surface_area+=Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).get_area();
+ } else {
+ //not completely enclosed, will need to be clipped..
+ Vector<Vector3> poly;
+ poly.push_back(p_triangle->vertices[0]);
+ poly.push_back(p_triangle->vertices[1]);
+ poly.push_back(p_triangle->vertices[2]);
+
+ //clip
+ for(int i=0;i<3;i++) {
+
+ //top plane
+ Plane p(0,0,0,0);
+ p.normal[i]=1.0;
+ p.d=p_aabb.pos[i]+p_aabb.size[i];
+ poly=Geometry::clip_polygon(poly,p);
+
+ //bottom plane
+ p.normal[i]=-1.0;
+ p.d=-p_aabb.pos[i];
+ poly=Geometry::clip_polygon(poly,p);
+ }
+ //calculate area
+ for(int i=2;i<poly.size();i++) {
+ p_octant->surface_area+=Face3(poly[0],poly[i-1],poly[i]).get_area();
+ }
+ }
+
+ } else {
+
+
+ for(int i=0;i<8;i++) {
+
+ AABB aabb=p_aabb;
+ aabb.size*=0.5;
+ if (i&1)
+ aabb.pos.x+=aabb.size.x;
+ if (i&2)
+ aabb.pos.y+=aabb.size.y;
+ if (i&4)
+ aabb.pos.z+=aabb.size.z;
+
+ AABB fit_aabb=aabb;
+ //fit_aabb=fit_aabb.grow(bvh->aabb.size.x*0.0001);
+
+ if (!Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).intersects_aabb(fit_aabb))
+ continue;
+
+ if (!p_octant->children[i]) {
+ p_octant->children[i]=memnew(Octant);
+ if (p_depth==0) {
+ p_octant->children[i]->leaf=true;
+ p_octant->children[i]->light_accum[0]=0;
+ p_octant->children[i]->light_accum[1]=0;
+ p_octant->children[i]->light_accum[2]=0;
+ p_octant->children[i]->offset[0]=aabb.pos.x+aabb.size.x*0.5;
+ p_octant->children[i]->offset[1]=aabb.pos.y+aabb.size.y*0.5;
+ p_octant->children[i]->offset[2]=aabb.pos.z+aabb.size.z*0.5;
+ p_octant->children[i]->surface_area=0;
+ p_octant->children[i]->next_leaf=leaf_list;
+ leaf_list=p_octant->children[i];
+ cell_count++;
+ } else {
+
+ p_octant->children[i]->leaf=false;
+ for(int j=0;j<8;j++) {
+ p_octant->children[i]->children[j]=0;
+ }
+ }
+ }
+
+ _octree_insert(aabb,p_octant->children[i],p_triangle,p_depth-1);
+ }
+ }
+}
+
+
+void BakedLightBaker::_make_octree() {
+
+ AABB base = bvh->aabb;
+ float lal=base.get_longest_axis_size();
+ //must be square because we want square blocks
+ base.size.x=lal;
+ base.size.y=lal;
+ base.size.z=lal;
+ base.grow_by(lal*0.001); //for precision
+ octree_aabb=base;
+
+ cell_size=base.size.x;
+ for(int i=0;i<=octree_depth;i++)
+ cell_size/=2.0;
+
+ octree = memnew( Octant );
+ octree->leaf=false;
+ for(int i=0;i<8;i++)
+ octree->children[i]=NULL;
+
+ for(int i=0;i<triangles.size();i++) {
+
+ _octree_insert(octree_aabb,octree,&triangles[i],octree_depth-1);
+ }
+
+}
+
+
+void BakedLightBaker::_plot_light(const Vector3& p_plot_pos,const AABB& p_plot_aabb, Octant *p_octant, const AABB& p_aabb,const Color& p_light) {
+
+
+ if (p_octant->leaf) {
+
+ float r=cell_size*plot_size;
+ Vector3 center=p_aabb.pos+p_aabb.size*0.5;
+ float d = p_plot_pos.distance_to(center);
+ if (d>r)
+ return; //oh crap! outside radius
+ float intensity = 1.0 - (d/r)*(d/r); //not gauss but..
+ p_octant->light_accum[0]+=p_light.r*intensity;
+ p_octant->light_accum[1]+=p_light.g*intensity;
+ p_octant->light_accum[2]+=p_light.b*intensity;
+
+ } else {
+
+ for(int i=0;i<8;i++) {
+
+ if (!p_octant->children[i])
+ continue;
+
+ AABB aabb=p_aabb;
+ aabb.size*=0.5;
+ if (i&1)
+ aabb.pos.x+=aabb.size.x;
+ if (i&2)
+ aabb.pos.y+=aabb.size.y;
+ if (i&4)
+ aabb.pos.z+=aabb.size.z;
+
+
+ if (!aabb.intersects(p_plot_aabb))
+ continue;
+
+ _plot_light(p_plot_pos,p_plot_aabb,p_octant->children[i],aabb,p_light);
+
+ }
+
+ }
+}
+
+
+void BakedLightBaker::_throw_ray(const Vector3& p_begin, const Vector3& p_end,const Color& p_light,float *p_att_curve,float p_att_curve_len,int p_bounces) {
+
+
+ uint32_t* stack = ray_stack;
+ BVH **bstack = bvh_stack;
+
+ enum {
+ TEST_AABB_BIT=0,
+ VISIT_LEFT_BIT=1,
+ VISIT_RIGHT_BIT=2,
+ VISIT_DONE_BIT=3,
+
+
+ };
+
+ Vector3 n = (p_end-p_begin).normalized();
+ real_t d=1e10;
+ bool inters=false;
+ Vector3 r_normal;
+ Vector3 r_point;
+
+ //for(int i=0;i<max_depth;i++)
+ // stack[i]=0;
+
+ int level=0;
+ //AABB ray_aabb;
+ //ray_aabb.pos=p_begin;
+ //ray_aabb.expand_to(p_end);
+
+
+ const BVH *bvhptr = bvh;
+
+ bstack[0]=bvh;
+ stack[0]=TEST_AABB_BIT;
+
+
+ while(true) {
+
+ uint32_t mode = stack[level];
+ const BVH &b = *bstack[level];
+ bool done=false;
+
+ switch(mode) {
+ case TEST_AABB_BIT: {
+
+ if (b.leaf) {
+
+
+ Face3 f3(b.leaf->vertices[0],b.leaf->vertices[1],b.leaf->vertices[2]);
+
+
+ Vector3 res;
+
+ if (f3.intersects_segment(p_begin,p_end,&res)) {
+
+
+ float nd = n.dot(res);
+ if (nd<d) {
+
+ d=nd;
+ r_point=res;
+ r_normal=f3.get_plane().get_normal();
+ inters=true;
+ }
+
+ }
+
+ stack[level]=VISIT_DONE_BIT;
+ } else {
+
+
+ bool valid = b.aabb.intersects_segment(p_begin,p_end);
+ // bool valid = b.aabb.intersects(ray_aabb);
+
+ if (!valid) {
+
+ stack[level]=VISIT_DONE_BIT;
+
+ } else {
+
+ stack[level]=VISIT_LEFT_BIT;
+ }
+ }
+
+ } continue;
+ case VISIT_LEFT_BIT: {
+
+ stack[level]=VISIT_RIGHT_BIT;
+ bstack[level+1]=b.children[0];
+ stack[level+1]=TEST_AABB_BIT;
+ level++;
+
+ } continue;
+ case VISIT_RIGHT_BIT: {
+
+ stack[level]=VISIT_DONE_BIT;
+ bstack[level+1]=b.children[1];
+ stack[level+1]=TEST_AABB_BIT;
+ level++;
+ } continue;
+ case VISIT_DONE_BIT: {
+
+ if (level==0) {
+ done=true;
+ break;
+ } else
+ level--;
+
+ } continue;
+ }
+
+
+ if (done)
+ break;
+ }
+
+
+ if (inters) {
+
+ //print_line("collision!");
+ if (n.dot(r_normal)>0)
+ r_normal=-r_normal;
+
+ //ok...
+ Color diffuse_at_point(0.8,0.8,0.8);
+ Color specular_at_point(0.8,0.8,0.8);
+
+ AABB aabb;
+ aabb.pos=r_point;
+ aabb.pos-=Vector3(1,1,1)*cell_size*plot_size;
+ aabb.size=Vector3(2,2,2)*cell_size*plot_size;
+
+ _plot_light(r_point,aabb,octree,octree_aabb,p_light);
+
+ }
+
+}
+
+
+
+
+
+
+float BakedLightBaker::get_normalization() const {
+
+ float nrg=0;
+ for(int i=0;i<directional_lights.size();i++) {
+
+ const DirLight &dl=directional_lights[i];
+ float total_area = dl.left.length()*2*dl.up.length()*2;
+ float cell_area = cell_size*cell_size;;
+ nrg+= dl.energy * (dl.rays_thrown * cell_area / total_area);
+ nrg*=5;
+ }
+
+ return nrg;
+}
+
+void BakedLightBaker::throw_rays(int p_amount) {
+
+
+
+ for(int i=0;i<directional_lights.size();i++) {
+
+ DirLight &dl=directional_lights[i];
+
+ float sr = Math::sqrt(p_amount);
+ float aspect = dl.up.length()/dl.left.length();
+
+
+ for(int j=0;j<p_amount;j++) {
+ Vector3 from = dl.pos;
+ from+=dl.up*(Math::randf()*2.0-1.0);
+ from+=dl.left*(Math::randf()*2.0-1.0);
+ Vector3 to = from+dl.dir*dl.length;
+ Color col=dl.diffuse;
+ col.r*=dl.energy;
+ col.g*=dl.energy;
+ col.b*=dl.energy;
+ dl.rays_thrown++;
+ _throw_ray(from,to,col,NULL,0,max_bounces);
+ }
+
+
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+void BakedLightBaker::bake(Node* p_node) {
+
+ cell_count=0;
+
+ _parse_geometry(p_node);
+ _fix_lights();
+ _make_bvh();
+ _make_octree();
+
+}
+
+
+
+
+void BakedLightEditor::_node_removed(Node *p_node) {
+
+ if(p_node==node) {
+ node=NULL;
+ p_node->remove_child(preview);
+ preview->set_mesh(Ref<Mesh>());
+ hide();
+ }
+
+}
+
+
+
+void BakedLightEditor::_menu_option(int p_option) {
+
+
+ switch(p_option) {
+
+
+ case MENU_OPTION_BAKE: {
+
+ ERR_FAIL_COND(!node);
+ preview->set_mesh(Ref<Mesh>());
+ baker->base_inv=node->get_global_transform().affine_inverse();
+ baker->bake(node);
+ baker->throw_rays(100000);
+ float norm = baker->get_normalization();
+ float max_lum=0;
+
+ print_line("CELLS: "+itos(baker->cell_count));
+ DVector<Color> colors;
+ DVector<Vector3> vertices;
+ colors.resize(baker->cell_count*36);
+ vertices.resize(baker->cell_count*36);
+
+
+ {
+ DVector<Color>::Write cw=colors.write();
+ DVector<Vector3>::Write vw=vertices.write();
+ BakedLightBaker::Octant *oct = baker->leaf_list;
+ int vert_idx=0;
+
+ while(oct) {
+
+ Color color;
+ color.r=oct->light_accum[0]/norm;
+ color.g=oct->light_accum[1]/norm;
+ color.b=oct->light_accum[2]/norm;
+ float lum = color.get_v();
+ if (lum>max_lum)
+ max_lum=lum;
+
+ for (int i=0;i<6;i++) {
+
+
+ Vector3 face_points[4];
+ for (int j=0;j<4;j++) {
+
+ float v[3];
+ v[0]=1.0;
+ v[1]=1-2*((j>>1)&1);
+ v[2]=v[1]*(1-2*(j&1));
+
+ for (int k=0;k<3;k++) {
+
+ if (i<3)
+ face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1);
+ else
+ face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1);
+ }
+ }
+
+ for(int j=0;j<4;j++) {
+ face_points[j]*=baker->cell_size;
+ face_points[j]+=Vector3(oct->offset[0],oct->offset[1],oct->offset[2]);
+ }
+
+#define ADD_VTX(m_idx) \
+ vw[vert_idx]=face_points[m_idx]; \
+ cw[vert_idx]=color; \
+ vert_idx++;
+
+ //tri 1
+ ADD_VTX(0);
+ ADD_VTX(1);
+ ADD_VTX(2);
+ //tri 2
+ ADD_VTX(2);
+ ADD_VTX(3);
+ ADD_VTX(0);
+
+#undef ADD_VTX
+
+ }
+
+ oct=oct->next_leaf;
+ }
+
+
+ }
+
+ print_line("max lum: "+rtos(max_lum));
+ Array a;
+ a.resize(Mesh::ARRAY_MAX);
+ a[Mesh::ARRAY_VERTEX]=vertices;
+ a[Mesh::ARRAY_COLOR]=colors;
+
+ Ref<FixedMaterial> matcol = memnew( FixedMaterial );
+ matcol->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
+ matcol->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
+ matcol->set_flag(FixedMaterial::FLAG_UNSHADED,true);
+ matcol->set_flag(FixedMaterial::FLAG_DOUBLE_SIDED,true);
+ matcol->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1));
+ Ref<Mesh> m = memnew( Mesh );
+ m->add_surface(Mesh::PRIMITIVE_TRIANGLES,a);
+ m->surface_set_material(0,matcol);
+ preview->set_mesh(m);
+
+
+
+
+
+ } break;
+ case MENU_OPTION_CLEAR: {
+
+
+
+ } break;
+
+ }
+}
+
+
+void BakedLightEditor::edit(BakedLight *p_baked_light) {
+
+ if (node==p_baked_light)
+ return;
+ if (node) {
+ node->remove_child(preview);
+ }
+
+ node=p_baked_light;
+
+ if (node)
+ node->add_child(preview);
+
+}
+
+
+
+void BakedLightEditor::_bind_methods() {
+
+ ObjectTypeDB::bind_method("_menu_option",&BakedLightEditor::_menu_option);
+}
+
+BakedLightEditor::BakedLightEditor() {
+
+
+ options = memnew( MenuButton );
+
+ options->set_text("BakedLight");
+ options->get_popup()->add_item("Bake..",MENU_OPTION_BAKE);
+ options->get_popup()->add_item("Clear",MENU_OPTION_CLEAR);
+ options->get_popup()->connect("item_pressed", this,"_menu_option");
+
+
+ err_dialog = memnew( AcceptDialog );
+ add_child(err_dialog);
+ node=NULL;
+ baker = memnew( BakedLightBaker );
+ preview = memnew( MeshInstance );
+}
+
+BakedLightEditor::~BakedLightEditor() {
+
+ memdelete(baker);
+}
+
+void BakedLightEditorPlugin::edit(Object *p_object) {
+
+ baked_light_editor->edit(p_object->cast_to<BakedLight>());
+}
+
+bool BakedLightEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_type("BakedLight");
+}
+
+void BakedLightEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+ baked_light_editor->show();
+ baked_light_editor->options->show();
+ } else {
+
+ baked_light_editor->hide();
+ baked_light_editor->options->show();
+ baked_light_editor->edit(NULL);
+ if (baked_light_editor->node) {
+ baked_light_editor->node->remove_child(baked_light_editor->preview);
+ baked_light_editor->node=NULL;
+ }
+ }
+
+}
+
+BakedLightEditorPlugin::BakedLightEditorPlugin(EditorNode *p_node) {
+
+ editor=p_node;
+ baked_light_editor = memnew( BakedLightEditor );
+ editor->get_viewport()->add_child(baked_light_editor);
+ add_custom_control(CONTAINER_SPATIAL_EDITOR_MENU,baked_light_editor->options);
+ baked_light_editor->hide();
+ baked_light_editor->options->hide();
+}
+
+
+BakedLightEditorPlugin::~BakedLightEditorPlugin()
+{
+}
+
+
diff --git a/tools/editor/plugins/baked_light_editor_plugin.h b/tools/editor/plugins/baked_light_editor_plugin.h
new file mode 100644
index 0000000000..698d3f825f
--- /dev/null
+++ b/tools/editor/plugins/baked_light_editor_plugin.h
@@ -0,0 +1,70 @@
+#ifndef BAKED_LIGHT_EDITOR_PLUGIN_H
+#define BAKED_LIGHT_EDITOR_PLUGIN_H
+
+#include "tools/editor/editor_plugin.h"
+#include "tools/editor/editor_node.h"
+#include "scene/3d/baked_light.h"
+#include "scene/gui/spin_box.h"
+
+/**
+ @author Juan Linietsky <reduzio@gmail.com>
+*/
+
+
+class BakedLightBaker;
+class MeshInstance;
+
+class BakedLightEditor : public Control {
+
+ OBJ_TYPE(BakedLightEditor, Control );
+
+
+ MeshInstance *preview;
+ BakedLightBaker *baker;
+ AcceptDialog *err_dialog;
+
+ MenuButton * options;
+ BakedLight *node;
+
+ enum Menu {
+
+ MENU_OPTION_BAKE,
+ MENU_OPTION_CLEAR
+ };
+
+ void _menu_option(int);
+
+friend class BakedLightEditorPlugin;
+protected:
+ void _node_removed(Node *p_node);
+ static void _bind_methods();
+public:
+
+ void edit(BakedLight *p_baked_light);
+ BakedLightEditor();
+ ~BakedLightEditor();
+};
+
+class BakedLightEditorPlugin : public EditorPlugin {
+
+ OBJ_TYPE( BakedLightEditorPlugin, EditorPlugin );
+
+ BakedLightEditor *baked_light_editor;
+ EditorNode *editor;
+
+public:
+
+ virtual String get_name() const { return "BakedLight"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_node);
+ virtual bool handles(Object *p_node) const;
+ virtual void make_visible(bool p_visible);
+
+ BakedLightEditorPlugin(EditorNode *p_node);
+ ~BakedLightEditorPlugin();
+
+};
+
+#endif // MULTIMESH_EDITOR_PLUGIN_H
+
+
diff --git a/tools/editor/plugins/sample_editor_plugin.cpp b/tools/editor/plugins/sample_editor_plugin.cpp
index f55d6640c2..e3fad58a89 100644
--- a/tools/editor/plugins/sample_editor_plugin.cpp
+++ b/tools/editor/plugins/sample_editor_plugin.cpp
@@ -95,93 +95,98 @@ void SampleEditor::generate_preview_texture(const Ref<Sample>& p_sample,Ref<Imag
if (len<1)
return;
- for(int i=0;i<w;i++) {
- // i trust gcc will optimize this loop
- float max[2]={-1e10,-1e10};
- float min[2]={1e10,1e10};
- int c=stereo?2:1;
- int from = i*len/w;
- int to = (i+1)*len/w;
- if (to>=len)
- to=len-1;
-
- if (_16) {
- const int16_t*src =(const int16_t*)sdata;
-
- for(int j=0;j<c;j++) {
-
- for(int k=from;k<=to;k++) {
-
- float v = src[k*c+j]/32768.0;
- if (v>max[j])
- max[j]=v;
- if (v<min[j])
- min[j]=v;
+ if (p_sample->get_format()==Sample::FORMAT_IMA_ADPCM) {
+
+
+ } else {
+ for(int i=0;i<w;i++) {
+ // i trust gcc will optimize this loop
+ float max[2]={-1e10,-1e10};
+ float min[2]={1e10,1e10};
+ int c=stereo?2:1;
+ int from = i*len/w;
+ int to = (i+1)*len/w;
+ if (to>=len)
+ to=len-1;
+
+ if (_16) {
+ const int16_t*src =(const int16_t*)sdata;
+
+ for(int j=0;j<c;j++) {
+
+ for(int k=from;k<=to;k++) {
+
+ float v = src[k*c+j]/32768.0;
+ if (v>max[j])
+ max[j]=v;
+ if (v<min[j])
+ min[j]=v;
+ }
+
}
+ } else {
- }
- } else {
+ const int8_t*src =(const int8_t*)sdata;
- const int8_t*src =(const int8_t*)sdata;
+ for(int j=0;j<c;j++) {
- for(int j=0;j<c;j++) {
+ for(int k=from;k<=to;k++) {
- for(int k=from;k<=to;k++) {
+ float v = src[k*c+j]/128.0;
+ if (v>max[j])
+ max[j]=v;
+ if (v<min[j])
+ min[j]=v;
+ }
- float v = src[k*c+j]/128.0;
- if (v>max[j])
- max[j]=v;
- if (v<min[j])
- min[j]=v;
}
-
}
- }
- if (!stereo) {
- for(int j=0;j<h;j++) {
- float v = (j/(float)h) * 2.0 - 1.0;
- uint8_t* imgofs = &imgw[(j*w+i)*3];
- if (v>min[0] && v<max[0]) {
- imgofs[0]=255;
- imgofs[1]=150;
- imgofs[2]=80;
- } else {
- imgofs[0]=0;
- imgofs[1]=0;
- imgofs[2]=0;
+ if (!stereo) {
+ for(int j=0;j<h;j++) {
+ float v = (j/(float)h) * 2.0 - 1.0;
+ uint8_t* imgofs = &imgw[(j*w+i)*3];
+ if (v>min[0] && v<max[0]) {
+ imgofs[0]=255;
+ imgofs[1]=150;
+ imgofs[2]=80;
+ } else {
+ imgofs[0]=0;
+ imgofs[1]=0;
+ imgofs[2]=0;
+ }
}
- }
- } else {
-
- for(int j=0;j<h;j++) {
-
- int half,ofs;
- float v;
- if (j<(h/2)) {
- half=0;
- ofs=0;
- v = (j/(float)(h/2)) * 2.0 - 1.0;
- } else {
- half=1;
- ofs=h/2;
- v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0;
+ } else {
+
+ for(int j=0;j<h;j++) {
+
+ int half,ofs;
+ float v;
+ if (j<(h/2)) {
+ half=0;
+ ofs=0;
+ v = (j/(float)(h/2)) * 2.0 - 1.0;
+ } else {
+ half=1;
+ ofs=h/2;
+ v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0;
+ }
+
+ uint8_t* imgofs = &imgw[(j*w+i)*3];
+ if (v>min[half] && v<max[half]) {
+ imgofs[0]=255;
+ imgofs[1]=150;
+ imgofs[2]=80;
+ } else {
+ imgofs[0]=0;
+ imgofs[1]=0;
+ imgofs[2]=0;
+ }
}
- uint8_t* imgofs = &imgw[(j*w+i)*3];
- if (v>min[half] && v<max[half]) {
- imgofs[0]=255;
- imgofs[1]=150;
- imgofs[2]=80;
- } else {
- imgofs[0]=0;
- imgofs[1]=0;
- imgofs[2]=0;
- }
}
}
-
}
imgdata = DVector<uint8_t>::Write();
diff --git a/tools/editor/plugins/sample_library_editor_plugin.cpp b/tools/editor/plugins/sample_library_editor_plugin.cpp
index 86ac1671ae..84143dcd4b 100644
--- a/tools/editor/plugins/sample_library_editor_plugin.cpp
+++ b/tools/editor/plugins/sample_library_editor_plugin.cpp
@@ -262,7 +262,7 @@ void SampleLibraryEditor::_update_library() {
ti->set_editable(2,false);
ti->set_selectable(2,false);
Ref<Sample> s = sample_library->get_sample(E->get());
- ti->set_text(2,String()+/*itos(s->get_length())+" frames ("+String::num(s->get_length()/(float)s->get_mix_rate(),2)+" s), "+*/(s->get_format()==Sample::FORMAT_PCM16?"16 Bits, ":"8 bits, ")+(s->is_stereo()?"Stereo":"Mono"));
+ ti->set_text(2,String()+/*itos(s->get_length())+" frames ("+String::num(s->get_length()/(float)s->get_mix_rate(),2)+" s), "+*/(s->get_format()==Sample::FORMAT_PCM16?"16 Bits, ":(s->get_format()==Sample::FORMAT_PCM8?"8 bits, ":"IMA-ADPCM,"))+(s->is_stereo()?"Stereo":"Mono"));
ti->set_cell_mode(3,TreeItem::CELL_MODE_RANGE);
ti->set_range_config(3,-60,24,0.01);
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp
index 8c16207887..2087345888 100644
--- a/tools/editor/property_editor.cpp
+++ b/tools/editor/property_editor.cpp
@@ -261,12 +261,12 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty
for(int i=0;i<2;i++) {
Point2 ofs(4,4);
- ofs.y+=16*i;
+ ofs.y+=22*i;
for(int j=0;j<10;j++) {
- CheckButton *c=checks20[i*10+j];
+ Button *c=checks20[i*10+j];
Point2 o=ofs;
- o.x+=j*16;
+ o.x+=j*22;
if (j>=5)
o.x+=4;
c->set_pos(o);
@@ -277,7 +277,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty
}
- set_size(checks20[19]->get_pos()+Size2(12,17));
+ set_size(checks20[19]->get_pos()+Size2(20,25));
} else if (hint==PROPERTY_HINT_EXP_EASING) {
@@ -1560,7 +1560,9 @@ CustomPropertyEditor::CustomPropertyEditor() {
}
for(int i=0;i<20;i++) {
- checks20[i]=memnew( CheckButton );
+ checks20[i]=memnew( Button );
+ checks20[i]->set_toggle_mode(true);
+ checks20[i]->set_focus_mode(FOCUS_NONE);
add_child(checks20[i]);
checks20[i]->hide();
checks20[i]->connect("pressed",this,"_action_pressed",make_binds(i));
diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h
index 7ee14679c1..f13deab1ae 100644
--- a/tools/editor/property_editor.h
+++ b/tools/editor/property_editor.h
@@ -92,7 +92,7 @@ class CustomPropertyEditor : public Popup {
ColorPicker *color_picker;
TextEdit *text_edit;
bool read_only;
- CheckButton *checks20[20];
+ Button *checks20[20];
Control *easing_draw;