summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2014-10-27 22:54:32 -0300
committerJuan Linietsky <reduzio@gmail.com>2014-10-27 22:54:32 -0300
commite82dc402052a47b44bb3bcf50ee4801257f92778 (patch)
tree01c2cd8692b5569cae778f6504b76b3d1f9ccdad
parent9608d4255eb6c76b1c4496f4494c829133e096f4 (diff)
-Much improvement to baked light baker
-Fixed many bugs in stretch mode -Fixes to camera project and unproject as consequence of the above -added setget to script (documented in script doc) -more fixes to collada exporter for blender
-rw-r--r--SConstruct1
-rw-r--r--core/globals.cpp6
-rw-r--r--core/io/config_file.cpp7
-rw-r--r--core/math/quick_hull.cpp2
-rw-r--r--demos/3d/platformer/tiles.resbin81338 -> 81631 bytes
-rw-r--r--drivers/gles1/rasterizer_gles1.cpp19
-rw-r--r--drivers/gles1/rasterizer_gles1.h11
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp180
-rw-r--r--drivers/gles2/rasterizer_gles2.h20
-rw-r--r--drivers/gles2/shaders/material.glsl44
-rw-r--r--drivers/ogg/SCsub3
-rw-r--r--drivers/theora/SCsub3
-rw-r--r--drivers/theoraplayer/SCsub14
-rw-r--r--drivers/vorbis/SCsub6
-rw-r--r--drivers/vorbis/audio_stream_ogg_vorbis.cpp2
-rw-r--r--modules/gdscript/gd_compiler.cpp10
-rw-r--r--modules/gdscript/gd_editor.cpp6
-rw-r--r--modules/gdscript/gd_parser.cpp129
-rw-r--r--modules/gdscript/gd_parser.h2
-rw-r--r--modules/gdscript/gd_script.cpp33
-rw-r--r--modules/gdscript/gd_script.h11
-rw-r--r--modules/gdscript/gd_tokenizer.cpp4
-rw-r--r--modules/gdscript/gd_tokenizer.h1
-rw-r--r--modules/gdscript/register_types.cpp4
-rw-r--r--modules/gridmap/grid_map.cpp2
-rw-r--r--platform/android/export/export.cpp35
-rw-r--r--platform/isim/SCsub9
-rw-r--r--platform/isim/detect.py14
-rw-r--r--platform/windows/detect.py2
-rw-r--r--platform/x11/detect.py5
-rw-r--r--scene/3d/baked_light_instance.cpp78
-rw-r--r--scene/3d/baked_light_instance.h42
-rw-r--r--scene/3d/camera.cpp19
-rw-r--r--scene/3d/skeleton.cpp16
-rw-r--r--scene/3d/skeleton.h2
-rw-r--r--scene/3d/visual_instance.cpp12
-rw-r--r--scene/3d/visual_instance.h1
-rw-r--r--scene/animation/animation_player.cpp2
-rw-r--r--scene/main/scene_main_loop.h3
-rw-r--r--scene/main/viewport.cpp31
-rw-r--r--scene/main/viewport.h5
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/baked_light.cpp94
-rw-r--r--scene/resources/baked_light.h25
-rw-r--r--scene/resources/material.cpp4
-rw-r--r--servers/visual/rasterizer.h7
-rw-r--r--servers/visual/rasterizer_dummy.cpp20
-rw-r--r--servers/visual/rasterizer_dummy.h11
-rw-r--r--servers/visual/visual_server_raster.cpp639
-rw-r--r--servers/visual/visual_server_raster.h66
-rw-r--r--servers/visual/visual_server_wrap_mt.h17
-rw-r--r--servers/visual_server.h30
-rw-r--r--tools/collada/collada.cpp2
-rw-r--r--tools/docdump/makemd.py2
-rw-r--r--tools/editor/plugins/baked_light_baker.cpp606
-rw-r--r--tools/editor/plugins/baked_light_baker.h48
-rw-r--r--tools/editor/plugins/baked_light_baker_cmpxchg.cpp84
-rw-r--r--tools/editor/plugins/baked_light_editor_plugin.cpp18
-rw-r--r--tools/editor/plugins/baked_light_editor_plugin.h5
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp2
-rw-r--r--tools/export/blender25/io_scene_dae/export_dae.py10
61 files changed, 2148 insertions, 339 deletions
diff --git a/SConstruct b/SConstruct
index 7589ab3e6c..fc9c7dca35 100644
--- a/SConstruct
+++ b/SConstruct
@@ -99,6 +99,7 @@ opts.Add('vorbis','Build Ogg Vorbis Support: (yes/no)','yes')
opts.Add('minizip','Build Minizip Archive Support: (yes/no)','yes')
opts.Add('squish','Squish BC Texture Compression in editor (yes/no)','yes')
opts.Add('theora','Theora Video (yes/no)','yes')
+opts.Add('use_theoraplayer_binary', "Use precompiled binaries from libtheoraplayer for ogg/theora/vorbis (yes/no)", "no")
opts.Add('freetype','Freetype support in editor','yes')
opts.Add('speex','Speex Audio (yes/no)','yes')
opts.Add('xml','XML Save/Load support (yes/no)','yes')
diff --git a/core/globals.cpp b/core/globals.cpp
index 5be53fd853..94fa331bed 100644
--- a/core/globals.cpp
+++ b/core/globals.cpp
@@ -566,9 +566,11 @@ static Variant _decode_variant(const String& p_string) {
ERR_FAIL_COND_V(params.size()!=1 && params.size()!=2,Variant());
int scode=0;
- if (params[0].is_numeric())
+ if (params[0].is_numeric()) {
scode=params[0].to_int();
- else
+ if (scode<10)
+ scode+=KEY_0;
+ } else
scode=find_keycode(params[0]);
InputEvent ie;
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index 45e8cf69ab..b707fd9c13 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -471,9 +471,12 @@ static Variant _decode_variant(const String& p_string) {
ERR_FAIL_COND_V(params.size()!=1 && params.size()!=2,Variant());
int scode=0;
- if (params[0].is_numeric())
+ if (params[0].is_numeric()) {
scode=params[0].to_int();
- else
+ if (scode < 10) {
+ scode=KEY_0+scode;
+ }
+ } else
scode=find_keycode(params[0]);
InputEvent ie;
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index 136a103eef..a417cdaddf 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -63,7 +63,7 @@ Error QuickHull::build(const Vector<Vector3>& p_points, Geometry::MeshData &r_me
Vector3 sp = p_points[i].snapped(0.0001);
if (valid_cache.has(sp)) {
valid_points[i]=false;
- print_line("INVALIDATED: "+itos(i));
+ //print_line("INVALIDATED: "+itos(i));
}else {
valid_points[i]=true;
valid_cache.insert(sp);
diff --git a/demos/3d/platformer/tiles.res b/demos/3d/platformer/tiles.res
index 53534788a1..d4fb779ff1 100644
--- a/demos/3d/platformer/tiles.res
+++ b/demos/3d/platformer/tiles.res
Binary files differ
diff --git a/drivers/gles1/rasterizer_gles1.cpp b/drivers/gles1/rasterizer_gles1.cpp
index 02de063bda..00fc85c41c 100644
--- a/drivers/gles1/rasterizer_gles1.cpp
+++ b/drivers/gles1/rasterizer_gles1.cpp
@@ -5365,6 +5365,18 @@ Variant RasterizerGLES1::environment_fx_get_param(RID p_env,VS::EnvironmentFxPar
}
+/* SAMPLED LIGHT */
+
+RID RasterizerGLES1::sampled_light_dp_create(int p_width,int p_height) {
+
+ return sampled_light_owner.make_rid(memnew(SampledLight));
+}
+
+void RasterizerGLES1::sampled_light_dp_update(RID p_sampled_light, const Color *p_data, float p_multiplier) {
+
+
+}
+
/*MISC*/
bool RasterizerGLES1::is_texture(const RID& p_rid) const {
@@ -5559,6 +5571,13 @@ void RasterizerGLES1::free(const RID& p_rid) {
environment_owner.free(p_rid);
memdelete( env );
+ } else if (sampled_light_owner.owns(p_rid)) {
+
+ SampledLight *sampled_light = sampled_light_owner.get( p_rid );
+ ERR_FAIL_COND(!sampled_light);
+
+ sampled_light_owner.free(p_rid);
+ memdelete( sampled_light );
};
}
diff --git a/drivers/gles1/rasterizer_gles1.h b/drivers/gles1/rasterizer_gles1.h
index cca953eed0..0995089dd7 100644
--- a/drivers/gles1/rasterizer_gles1.h
+++ b/drivers/gles1/rasterizer_gles1.h
@@ -488,6 +488,13 @@ class RasterizerGLES1 : public Rasterizer {
mutable RID_Owner<Environment> environment_owner;
+ struct SampledLight {
+
+ int w,h;
+ };
+
+ mutable RID_Owner<SampledLight> sampled_light_owner;
+
struct ShadowBuffer;
struct LightInstance {
@@ -1190,6 +1197,10 @@ public:
virtual void environment_fx_set_param(RID p_env,VS::EnvironmentFxParam p_param,const Variant& p_value);
virtual Variant environment_fx_get_param(RID p_env,VS::EnvironmentFxParam p_param) const;
+ /* SAMPLED LIGHT */
+ virtual RID sampled_light_dp_create(int p_width,int p_height);
+ virtual void sampled_light_dp_update(RID p_sampled_light,const Color *p_data,float p_multiplier);
+
/*MISC*/
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index d596aad4b9..bb0fd2e593 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -5108,7 +5108,7 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) {
if (li->near_shadow_buffer) {
- glActiveTexture(GL_TEXTURE7);
+ glActiveTexture(GL_TEXTURE0+max_texture_units-1);
//if (read_depth_supported) {
glBindTexture(GL_TEXTURE_2D,li->near_shadow_buffer->depth);
@@ -5119,7 +5119,7 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) {
material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX,li->shadow_projection[0]);
material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXEL_SIZE,Vector2(1.0,1.0)/li->near_shadow_buffer->size);
- material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXTURE,7);
+ material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXTURE,max_texture_units-1);
if (shadow_filter==SHADOW_FILTER_ESM)
material_shader.set_uniform(MaterialShaderGLES2::ESM_MULTIPLIER,float(li->base->vars[VS::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER]));
@@ -5739,9 +5739,10 @@ void RasterizerGLES2::_render(const Geometry *p_geometry,const Material *p_mater
float twd=(1.0/mm->tw)*4.0;
float thd=1.0/mm->th;
float parm[3]={0.0,01.0,(1.0f/mm->tw)};
- glActiveTexture(GL_TEXTURE6);
+ glActiveTexture(GL_TEXTURE0+max_texture_units-2);
glDisableVertexAttribArray(6);
glBindTexture(GL_TEXTURE_2D,mm->tex_id);
+ material_shader.set_uniform(MaterialShaderGLES2::INSTANCE_MATRICES,GL_TEXTURE0+max_texture_units-2);
if (s->index_array_len>0) {
@@ -6042,7 +6043,7 @@ void RasterizerGLES2::_setup_skeleton(const Skeleton *p_skeleton) {
material_shader.set_conditional(MaterialShaderGLES2::USE_SKELETON,p_skeleton!=NULL);
if (p_skeleton && p_skeleton->tex_id) {
- glActiveTexture(GL_TEXTURE6);
+ glActiveTexture(GL_TEXTURE0+max_texture_units-2);
glBindTexture(GL_TEXTURE_2D,p_skeleton->tex_id);
}
@@ -6091,7 +6092,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;
-
+ float sampled_light_dp_multiplier=1.0;
bool prev_blend=false;
glDisable(GL_BLEND);
@@ -6110,6 +6111,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
bool bind_baked_light_octree=false;
bool bind_baked_lightmap=false;
bool additive=false;
+ bool bind_dp_sampler=false;
if (!shadow) {
@@ -6231,6 +6233,22 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE,false);
material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP,false);
+ material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_DP_SAMPLER,false);
+
+ if (e->instance->sampled_light.is_valid()) {
+
+ SampledLight *sl = sampled_light_owner.get(e->instance->sampled_light);
+ if (sl) {
+
+ baked_light=NULL; //can't mix
+ material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_DP_SAMPLER,true);
+ glActiveTexture(GL_TEXTURE0+max_texture_units-3);
+ glBindTexture(GL_TEXTURE_2D,sl->texture); //bind the texture
+ sampled_light_dp_multiplier=sl->multiplier;
+ bind_dp_sampler=true;
+ }
+ }
+
if (!additive && baked_light) {
@@ -6241,9 +6259,16 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
Texture *tex=texture_owner.get(baked_light->octree_texture);
if (tex) {
- glActiveTexture(GL_TEXTURE5);
+ glActiveTexture(GL_TEXTURE0+max_texture_units-3);
glBindTexture(tex->target,tex->tex_id); //bind the texture
}
+ if (baked_light->light_texture.is_valid()) {
+ Texture *texl=texture_owner.get(baked_light->light_texture);
+ if (texl) {
+ glActiveTexture(GL_TEXTURE0+max_texture_units-4);
+ glBindTexture(texl->target,texl->tex_id); //bind the light texture
+ }
+ }
}
} else if (baked_light->mode==VS::BAKED_LIGHT_LIGHTMAPS) {
@@ -6266,7 +6291,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
Texture *tex = texture_owner.get(texid);
if (tex) {
- glActiveTexture(GL_TEXTURE5);
+ glActiveTexture(GL_TEXTURE0+max_texture_units-3);
glBindTexture(tex->target,tex->tex_id); //bind the texture
}
@@ -6342,7 +6367,15 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LATTICE_SIZE, baked_light->octree_lattice_size);
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LATTICE_DIVIDE, baked_light->octree_lattice_divide);
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_STEPS, baked_light->octree_steps);
- material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_TEX,5);
+ material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_TEX,max_texture_units-3);
+ if (baked_light->light_texture.is_valid()) {
+
+ material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_TEX,max_texture_units-4);
+ material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_PIX_SIZE,baked_light->light_tex_pixel_size);
+ } else {
+ material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_TEX,max_texture_units-3);
+ material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_PIX_SIZE,baked_light->octree_tex_pixel_size);
+ }
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_MULTIPLIER,baked_light->texture_multiplier);
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_PIX_SIZE,baked_light->octree_tex_pixel_size);
@@ -6351,11 +6384,16 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
if (bind_baked_lightmap && (baked_light!=prev_baked_light || rebind)) {
- material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHTMAP, 5);
+ material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHTMAP, max_texture_units-3);
material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHTMAP_MULTIPLIER, baked_light->lightmap_multiplier);
}
+ if (bind_dp_sampler) {
+
+ material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_DP_SAMPLER_MULTIPLIER,sampled_light_dp_multiplier);
+ material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_DP_SAMPLER,max_texture_units-3);
+ }
_set_cull(e->mirror,p_reverse_cull);
@@ -6364,7 +6402,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
material_shader.set_uniform(MaterialShaderGLES2::CAMERA_INVERSE_TRANSFORM, p_view_transform_inverse);
material_shader.set_uniform(MaterialShaderGLES2::PROJECTION_TRANSFORM, p_projection);
if (skeleton && use_hw_skeleton_xform) {
- //material_shader.set_uniform(MaterialShaderGLES2::SKELETON_MATRICES,6);
+ material_shader.set_uniform(MaterialShaderGLES2::SKELETON_MATRICES,GL_TEXTURE0+max_texture_units-2);
material_shader.set_uniform(MaterialShaderGLES2::SKELTEX_PIXEL_SIZE,skeleton->pixel_size);
}
if (!shadow) {
@@ -7098,6 +7136,7 @@ void RasterizerGLES2::end_scene() {
_debug_shadows();
}
// _debug_luminances();
+ _debug_samplers();
}
@@ -7498,6 +7537,38 @@ void RasterizerGLES2::_debug_luminances() {
}
+void RasterizerGLES2::_debug_samplers() {
+ canvas_shader.set_conditional(CanvasShaderGLES2::DEBUG_ENCODED_32,false);
+ canvas_begin();
+ glDisable(GL_BLEND);
+ _set_color_attrib(Color(1,1,1,1));
+ canvas_shader.bind();
+
+
+ List<RID> samplers;
+ sampled_light_owner.get_owned_list(&samplers);
+
+ Size2 debug_size(128,128);
+ Size2 ofs;
+
+
+ for (List<RID>::Element *E=samplers.front();E;E=E->next()) {
+
+ SampledLight *sl=sampled_light_owner.get(E->get());
+
+ _debug_draw_shadow(sl->texture, Rect2( ofs, debug_size ));
+
+ ofs.x+=debug_size.x/2;
+ if ( (ofs.x+debug_size.x) > viewport.width ) {
+
+ ofs.x=0;
+ ofs.y+=debug_size.y;
+ }
+ }
+
+
+
+}
void RasterizerGLES2::_debug_shadows() {
canvas_begin();
@@ -8115,6 +8186,78 @@ Variant RasterizerGLES2::environment_fx_get_param(RID p_env,VS::EnvironmentFxPar
}
+
+
+RID RasterizerGLES2::sampled_light_dp_create(int p_width,int p_height) {
+
+ SampledLight *slight = memnew(SampledLight);
+ slight->w=p_width;
+ slight->h=p_height;
+ slight->multiplier=1.0;
+ slight->is_float=float_linear_supported;
+
+ glActiveTexture(GL_TEXTURE0);
+ glGenTextures(1,&slight->texture);
+ glBindTexture(GL_TEXTURE_2D, slight->texture);
+// for debug, but glitchy
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ // Remove artifact on the edges of the shadowmap
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+
+ if (slight->is_float) {
+#ifdef GLEW_ENABLED
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_width, p_height, 0, GL_RGBA, GL_FLOAT,NULL);
+#else
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_width, p_height, 0, GL_RGBA, GL_FLOAT,NULL);
+#endif
+ } else {
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_width, p_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ }
+
+ return sampled_light_owner.make_rid(slight);
+}
+
+void RasterizerGLES2::sampled_light_dp_update(RID p_sampled_light, const Color *p_data, float p_multiplier) {
+
+ SampledLight *slight = sampled_light_owner.get(p_sampled_light);
+ ERR_FAIL_COND(!slight);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, slight->texture);
+
+ if (slight->is_float) {
+
+#ifdef GLEW_ENABLED
+ glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,slight->w, slight->h, GL_RGBA, GL_FLOAT,p_data);
+#else
+ glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,slight->w, slight->h, GL_RGBA, GL_FLOAT,p_data);
+#endif
+
+ } else {
+ //convert to bytes
+ uint8_t *tex8 = (uint8_t*)alloca(slight->w*slight->h*4);
+ const float* src=(const float*)p_data;
+
+ for(int i=0;i<slight->w*slight->h*4;i++) {
+
+ tex8[i]=Math::fast_ftoi(CLAMP(src[i]*255.0,0.0,255.0));
+ }
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,slight->w, slight->h, GL_RGBA, GL_UNSIGNED_BYTE,p_data);
+ }
+
+ slight->multiplier=p_multiplier;
+
+}
+
/*MISC*/
bool RasterizerGLES2::is_texture(const RID& p_rid) const {
@@ -8334,6 +8477,13 @@ void RasterizerGLES2::free(const RID& p_rid) {
memdelete(render_target->texture_ptr);
render_target_owner.free(p_rid);
memdelete( render_target );
+ } else if (sampled_light_owner.owns(p_rid)) {
+
+ SampledLight *sampled_light = sampled_light_owner.get( p_rid );
+ ERR_FAIL_COND(!sampled_light);
+ glDeleteTextures(1,&sampled_light->texture);
+ sampled_light_owner.free(p_rid);
+ memdelete( sampled_light );
};
}
@@ -8926,6 +9076,9 @@ void RasterizerGLES2::init() {
latc_supported=true;
s3tc_srgb_supported=true;
use_anisotropic_filter=true;
+ float_linear_supported=true;
+ float_supported=true;
+
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&anisotropic_level);
anisotropic_level=MIN(anisotropic_level,float(GLOBAL_DEF("rasterizer/anisotropic_filter_level",4.0)));
#ifdef OSX_ENABLED
@@ -8970,7 +9123,10 @@ void RasterizerGLES2::init() {
GLint vtf;
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,&vtf);
- use_hw_skeleton_xform=vtf>0 && extensions.has("GL_OES_texture_float");
+ float_supported = extensions.has("GL_OES_texture_float");
+ use_hw_skeleton_xform=vtf>0 && float_supported;
+ float_linear_supported = extensions.has("GL_OES_texture_float_linear");
+
//if (extensions.has("GL_QCOM_tiled_rendering"))
// use_hw_skeleton_xform=false;
GLint mva;
@@ -9008,7 +9164,7 @@ void RasterizerGLES2::init() {
-
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_units);
//read_depth_supported=false;
{
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index dc2e22d240..91395054d9 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -86,6 +86,8 @@ class RasterizerGLES2 : public Rasterizer {
bool use_shadow_mapping;
bool use_fp16_fb;
bool srgb_supported;
+ bool float_supported;
+ bool float_linear_supported;
ShadowFilterTechnique shadow_filter;
@@ -704,6 +706,18 @@ class RasterizerGLES2 : public Rasterizer {
mutable RID_Owner<Environment> environment_owner;
+
+ struct SampledLight {
+
+ int w,h;
+ GLuint texture;
+ float multiplier;
+ bool is_float;
+ };
+
+ mutable RID_Owner<SampledLight> sampled_light_owner;
+
+
struct ViewportData {
//1x1 fbo+texture for storing previous HDR value
@@ -801,6 +815,7 @@ class RasterizerGLES2 : public Rasterizer {
RID shadow_material;
Material *shadow_mat_ptr;
+ int max_texture_units;
GLuint base_framebuffer;
GLuint gui_quad_buffer;
@@ -1071,6 +1086,8 @@ class RasterizerGLES2 : public Rasterizer {
void _debug_draw_shadows_type(Vector<ShadowBuffer>& p_shadows,Point2& ofs);
void _debug_shadows();
void _debug_luminances();
+ void _debug_samplers();
+
/***********/
@@ -1531,6 +1548,9 @@ public:
virtual void environment_fx_set_param(RID p_env,VS::EnvironmentFxParam p_param,const Variant& p_value);
virtual Variant environment_fx_get_param(RID p_env,VS::EnvironmentFxParam p_param) const;
+ /* SAMPLED LIGHT */
+ virtual RID sampled_light_dp_create(int p_width,int p_height);
+ virtual void sampled_light_dp_update(RID p_sampled_light, const Color *p_data, float p_multiplier);
/*MISC*/
diff --git a/drivers/gles2/shaders/material.glsl b/drivers/gles2/shaders/material.glsl
index 44337e1197..7d9aca4b4d 100644
--- a/drivers/gles2/shaders/material.glsl
+++ b/drivers/gles2/shaders/material.glsl
@@ -60,7 +60,7 @@ uniform float normal_mult;
#ifdef USE_SKELETON
attribute vec4 bone_indices; // attrib:6
attribute vec4 bone_weights; // attrib:7
-uniform highp sampler2D skeleton_matrices; // texunit:6
+uniform highp sampler2D skeleton_matrices;
uniform highp float skeltex_pixel_size;
#endif
@@ -76,7 +76,7 @@ attribute highp vec4 instance_row3; // attrib:11
#ifdef USE_TEXTURE_INSTANCING
attribute highp vec3 instance_uv; // attrib:6
-uniform highp sampler2D instance_matrices; // texunit:6
+uniform highp sampler2D instance_matrices;
#endif
@@ -595,8 +595,10 @@ uniform float time;
varying highp vec3 ambient_octree_coords;
uniform highp float ambient_octree_lattice_size;
uniform highp vec2 ambient_octree_pix_size;
+uniform highp vec2 ambient_octree_light_pix_size;
uniform highp float ambient_octree_lattice_divide;
uniform highp sampler2D ambient_octree_tex;
+uniform highp sampler2D ambient_octree_light_tex;
uniform float ambient_octree_multiplier;
uniform int ambient_octree_steps;
@@ -609,6 +611,12 @@ uniform float ambient_lightmap_multiplier;
#endif
+#ifdef ENABLE_AMBIENT_DP_SAMPLER
+
+uniform highp sampler2D ambient_dp_sampler;
+uniform float ambient_dp_sampler_multiplier;
+
+#endif
FRAGMENT_SHADER_GLOBALS
@@ -918,12 +926,12 @@ FRAGMENT_SHADER_CODE
}
//sample color
- octant_uv=(octant_uv+0.5)*ambient_octree_pix_size;
+ octant_uv=(octant_uv+0.5)*ambient_octree_light_pix_size;
highp vec3 sub=(mod(ambient_octree_coords,ld)/ld);
- octant_uv.xy+=sub.xy*ambient_octree_pix_size.xy;
- vec3 col_up=texture2D(ambient_octree_tex,octant_uv).rgb;
- octant_uv.y+=ambient_octree_pix_size.y*2.0;
- vec3 col_down=texture2D(ambient_octree_tex,octant_uv).rgb;
+ octant_uv.xy+=sub.xy*ambient_octree_light_pix_size.xy;
+ vec3 col_up=texture2D(ambient_octree_light_tex,octant_uv).rgb;
+ octant_uv.y+=ambient_octree_light_pix_size.y*2.0;
+ vec3 col_down=texture2D(ambient_octree_light_tex,octant_uv).rgb;
ambientmap_color=mix(col_up,col_down,sub.z)*ambient_octree_multiplier;
ambientmap_color*=diffuse.rgb;
@@ -934,6 +942,26 @@ FRAGMENT_SHADER_CODE
+#ifdef ENABLE_AMBIENT_DP_SAMPLER
+
+ vec3 ambientmap_color = vec3(0.0,0.0,0.0);
+
+ {
+
+ vec3 dp_normal = normalize((vec4(normal,0) * camera_inverse_transform).xyz);
+ vec2 ambient_uv = (dp_normal.xy / (1.0+abs(dp_normal.z)))*0.5+0.5; //dual paraboloid
+ ambient_uv.y*=0.5;
+ if (dp_normal.z<0) {
+
+ ambient_uv.y=(0.5-ambient_uv.y)+0.5;
+
+ }
+
+ ambientmap_color = texture2D(ambient_dp_sampler,ambient_uv ).rgb * ambient_dp_sampler_multiplier;
+ ambientmap_color*=diffuse.rgb;
+ }
+
+#endif
@@ -1224,7 +1252,7 @@ LIGHT_SHADER_CODE
#endif
-#if defined(ENABLE_AMBIENT_OCTREE) || defined(ENABLE_AMBIENT_LIGHTMAP)
+#if defined(ENABLE_AMBIENT_OCTREE) || defined(ENABLE_AMBIENT_LIGHTMAP) || defined(ENABLE_AMBIENT_DP_SAMPLER)
diffuse.rgb+=ambientmap_color;
#endif
diff --git a/drivers/ogg/SCsub b/drivers/ogg/SCsub
index 5cdc3ea1c0..dd59890064 100644
--- a/drivers/ogg/SCsub
+++ b/drivers/ogg/SCsub
@@ -6,5 +6,6 @@ ogg_sources = [
"ogg/framing.c",
]
-env.drivers_sources+=ogg_sources
+if env['theora'] != "yes" or env['use_theoraplayer_binary'] != "yes":
+ env.drivers_sources+=ogg_sources
diff --git a/drivers/theora/SCsub b/drivers/theora/SCsub
index d3e5838276..ecabce6c9d 100644
--- a/drivers/theora/SCsub
+++ b/drivers/theora/SCsub
@@ -32,6 +32,7 @@ sources = [
"theora/video_stream_theora.cpp",
]
-env.drivers_sources += sources
+if env['use_theoraplayer_binary'] != "yes":
+ env.drivers_sources += sources
diff --git a/drivers/theoraplayer/SCsub b/drivers/theoraplayer/SCsub
index 023b2c928b..979ff2ed1b 100644
--- a/drivers/theoraplayer/SCsub
+++ b/drivers/theoraplayer/SCsub
@@ -59,7 +59,6 @@ src/YUV/C/yuv420_grey_c.c
src/YUV/C/yuv420_yuv_c.c
src/YUV/C/yuv420_rgb_c.c
src/TheoraVideoFrame.cpp
-video_stream_theoraplayer.cpp
""")
if env["platform"] == "iphone":
@@ -79,7 +78,18 @@ if env["platform"] == "android":
env_theora.Append(CPPPATH=["#drivers/theoraplayer/include/theoraplayer", "#drivers/theoraplayer/src/YUV", "#drivers/theoraplayer/src/YUV/libyuv/include", "#drivers/theoraplayer/src/Theora", "#drivers/theoraplayer/src/AVFoundation"])
objs = []
-env_theora.add_source_files(objs, sources)
+
+env_theora.add_source_files(objs, ["video_stream_theoraplayer.cpp"])
+
+if env['use_theoraplayer_binary'] == "yes":
+ if env["platform"] == "iphone":
+ env.Append(LIBPATH=['#drivers/theoraplayer/lib/ios'])
+ env.Append(LIBS=['theoraplayer', 'ogg', 'theora', 'tremor'])
+ if env["platform"] == "windows":
+ env.Append(LIBPATH=['#drivers/theoraplayer/lib/windows'])
+ env.Append(LINKFLAGS=['libtheoraplayer_static.lib', 'libogg.lib', 'libtheora.lib', 'libvorbis.lib'])
+else:
+ env_theora.add_source_files(objs, sources)
env.drivers_sources += objs
diff --git a/drivers/vorbis/SCsub b/drivers/vorbis/SCsub
index 1c7cccc427..2c137629ac 100644
--- a/drivers/vorbis/SCsub
+++ b/drivers/vorbis/SCsub
@@ -3,6 +3,9 @@ Import('env')
sources = [
"vorbis/audio_stream_ogg_vorbis.cpp",
+]
+
+sources_lib = [
"vorbis/analysis.c",
#"vorbis/barkmel.c",
"vorbis/bitrate.c",
@@ -32,3 +35,6 @@ sources = [
env.drivers_sources += sources
+if env['theora'] != "yes" or env['use_theoraplayer_binary'] != "yes":
+ env.drivers_sources += sources_lib
+
diff --git a/drivers/vorbis/audio_stream_ogg_vorbis.cpp b/drivers/vorbis/audio_stream_ogg_vorbis.cpp
index d9b7b1d161..996f75d165 100644
--- a/drivers/vorbis/audio_stream_ogg_vorbis.cpp
+++ b/drivers/vorbis/audio_stream_ogg_vorbis.cpp
@@ -215,7 +215,7 @@ AudioStreamOGGVorbis::UpdateMode AudioStreamOGGVorbis::get_update_mode() const {
bool AudioStreamOGGVorbis::is_playing() const {
- return playing;
+ return playing || (get_total() - get_todo() -1 > 0);
}
float AudioStreamOGGVorbis::get_pos() const {
diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp
index 45eac23450..4c56468297 100644
--- a/modules/gdscript/gd_compiler.cpp
+++ b/modules/gdscript/gd_compiler.cpp
@@ -179,7 +179,7 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
//static function
if (codegen.script->member_indices.has(identifier)) {
- int idx = codegen.script->member_indices[identifier];
+ int idx = codegen.script->member_indices[identifier].index;
return idx|(GDFunction::ADDR_TYPE_MEMBER<<GDFunction::ADDR_BITS); //argument (stack root)
}
}
@@ -1507,8 +1507,12 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars
#endif
}
- int new_idx = p_script->member_indices.size();
- p_script->member_indices[name]=new_idx;
+ //int new_idx = p_script->member_indices.size();
+ GDScript::MemberInfo minfo;
+ minfo.index = p_script->member_indices.size();
+ minfo.setter = p_class->variables[i].setter;
+ minfo.getter = p_class->variables[i].getter;
+ p_script->member_indices[name]=minfo;
p_script->members.insert(name);
}
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp
index 9610f9827f..d1f511b46e 100644
--- a/modules/gdscript/gd_editor.cpp
+++ b/modules/gdscript/gd_editor.cpp
@@ -250,12 +250,12 @@ void GDScriptLanguage::debug_get_stack_level_members(int p_level,List<String> *p
ERR_FAIL_COND( script.is_null() );
- const Map<StringName,int>& mi = script->debug_get_member_indices();
+ const Map<StringName,GDScript::MemberInfo>& mi = script->debug_get_member_indices();
- for(const Map<StringName,int>::Element *E=mi.front();E;E=E->next()) {
+ for(const Map<StringName,GDScript::MemberInfo>::Element *E=mi.front();E;E=E->next()) {
p_members->push_back(E->key());
- p_values->push_back( instance->debug_get_member_by_index(E->get()));
+ p_values->push_back( instance->debug_get_member_by_index(E->get().index));
}
}
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index 915fb1e60f..659e19a9d0 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -2376,80 +2376,113 @@ void GDParser::_parse_class(ClassNode *p_class) {
member._export.name=member.identifier;
tokenizer->advance();
- p_class->variables.push_back(member);
+ if (tokenizer->get_token()==GDTokenizer::TK_OP_ASSIGN) {
- if (tokenizer->get_token()!=GDTokenizer::TK_OP_ASSIGN) {
+#ifdef DEBUG_ENABLED
+ int line = tokenizer->get_token_line();
+#endif
+ tokenizer->advance();
- if (autoexport) {
+ Node *subexpr=NULL;
- _set_error("Type-less export needs a constant expression assigned to infer type.");
+ subexpr = _parse_and_reduce_expression(p_class,false);
+ if (!subexpr)
return;
- }
- break;
- }
-#ifdef DEBUG_ENABLED
- int line = tokenizer->get_token_line();
-#endif
- tokenizer->advance();
- Node *subexpr=NULL;
+ if (autoexport) {
+ if (subexpr->type==Node::TYPE_ARRAY) {
- subexpr = _parse_and_reduce_expression(p_class,false);
- if (!subexpr)
- return;
+ member._export.type=Variant::ARRAY;
- if (autoexport) {
- if (subexpr->type==Node::TYPE_ARRAY) {
+ } else if (subexpr->type==Node::TYPE_DICTIONARY) {
- p_class->variables[p_class->variables.size()-1]._export.type=Variant::ARRAY;
+ member._export.type=Variant::DICTIONARY;
- } else if (subexpr->type==Node::TYPE_DICTIONARY) {
+ } else {
- p_class->variables[p_class->variables.size()-1]._export.type=Variant::DICTIONARY;
+ if (subexpr->type!=Node::TYPE_CONSTANT) {
- } else {
+ _set_error("Type-less export needs a constant expression assigned to infer type.");
+ return;
+ }
- if (subexpr->type!=Node::TYPE_CONSTANT) {
+ ConstantNode *cn = static_cast<ConstantNode*>(subexpr);
+ if (cn->value.get_type()==Variant::NIL) {
- _set_error("Type-less export needs a constant expression assigned to infer type.");
- return;
+ _set_error("Can't accept a null constant expression for infering export type.");
+ return;
+ }
+ member._export.type=cn->value.get_type();
}
+ }
+#ifdef TOOLS_ENABLED
+ if (subexpr->type==Node::TYPE_CONSTANT && member._export.type!=Variant::NIL) {
ConstantNode *cn = static_cast<ConstantNode*>(subexpr);
- if (cn->value.get_type()==Variant::NIL) {
-
- _set_error("Can't accept a null constant expression for infering export type.");
- return;
+ if (cn->value.get_type()!=Variant::NIL) {
+ member.default_value=cn->value;
}
- p_class->variables[p_class->variables.size()-1]._export.type=cn->value.get_type();
}
- }
-#ifdef TOOLS_ENABLED
- if (subexpr->type==Node::TYPE_CONSTANT && p_class->variables[p_class->variables.size()-1]._export.type!=Variant::NIL) {
+#endif
+
+ IdentifierNode *id = alloc_node<IdentifierNode>();
+ id->name=member.identifier;
+
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op=OperatorNode::OP_ASSIGN;
+ op->arguments.push_back(id);
+ op->arguments.push_back(subexpr);
+
+#ifdef DEBUG_ENABLED
+ NewLineNode *nl = alloc_node<NewLineNode>();
+ nl->line=line;
+ p_class->initializer->statements.push_back(nl);
+#endif
+ p_class->initializer->statements.push_back(op);
+
+
+
+ } else {
+
+ if (autoexport) {
- ConstantNode *cn = static_cast<ConstantNode*>(subexpr);
- if (cn->value.get_type()!=Variant::NIL) {
- p_class->variables[p_class->variables.size()-1].default_value=cn->value;
+ _set_error("Type-less export needs a constant expression assigned to infer type.");
+ return;
}
+
}
-#endif
+ if (tokenizer->get_token()==GDTokenizer::TK_PR_SETGET) {
- IdentifierNode *id = alloc_node<IdentifierNode>();
- id->name=member.identifier;
+ tokenizer->advance();
- OperatorNode *op = alloc_node<OperatorNode>();
- op->op=OperatorNode::OP_ASSIGN;
- op->arguments.push_back(id);
- op->arguments.push_back(subexpr);
+ if (tokenizer->get_token()!=GDTokenizer::TK_COMMA) {
+ //just comma means using only getter
+ if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER) {
+ _set_error("Expected identifier for setter function after 'notify'.");
+ }
-#ifdef DEBUG_ENABLED
- NewLineNode *nl = alloc_node<NewLineNode>();
- nl->line=line;
- p_class->initializer->statements.push_back(nl);
-#endif
- p_class->initializer->statements.push_back(op);
+ member.setter=tokenizer->get_token_identifier();
+
+ tokenizer->advance();
+ }
+
+ if (tokenizer->get_token()==GDTokenizer::TK_COMMA) {
+ //there is a getter
+ tokenizer->advance();
+
+ if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER) {
+ _set_error("Expected identifier for getter function after ','.");
+ }
+
+ member.getter=tokenizer->get_token_identifier();
+ tokenizer->advance();
+
+ }
+ }
+
+ p_class->variables.push_back(member);
_end_statement();
diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h
index 50b84d389a..16a9a85290 100644
--- a/modules/gdscript/gd_parser.h
+++ b/modules/gdscript/gd_parser.h
@@ -82,6 +82,8 @@ public:
Variant default_value;
#endif
StringName identifier;
+ StringName setter;
+ StringName getter;
};
struct Constant {
StringName identifier;
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index f0ef69df5b..b20fc51a03 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -1537,7 +1537,7 @@ void GDScript::_update_placeholder(PlaceHolderScriptInstance *p_placeholder) {
_GDScriptMemberSort ms;
ERR_CONTINUE(!scr->member_indices.has(E->key()));
- ms.index=scr->member_indices[E->key()];
+ ms.index=scr->member_indices[E->key()].index;
ms.name=E->key();
msort.push_back(ms);
@@ -1961,9 +1961,9 @@ const Map<StringName,GDFunction>& GDScript::debug_get_member_functions() const {
StringName GDScript::debug_get_member_by_index(int p_idx) const {
- for(const Map<StringName,int>::Element *E=member_indices.front();E;E=E->next()) {
+ for(const Map<StringName,MemberInfo>::Element *E=member_indices.front();E;E=E->next()) {
- if (E->get()==p_idx)
+ if (E->get().index==p_idx)
return E->key();
}
@@ -2002,11 +2002,18 @@ bool GDInstance::set(const StringName& p_name, const Variant& p_value) {
//member
{
- const Map<StringName,int>::Element *E = script->member_indices.find(p_name);
+ const Map<StringName,GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
if (E) {
- members[E->get()]=p_value;
+ members[E->get().index]=p_value;
+ if (E->get().setter) {
+ const Variant *val=&p_value;
+ Variant::CallError err;
+ call(E->get().setter,&val,1,err);
+ if (err.error==Variant::CallError::CALL_OK) {
+ return true; //function exists, call was successful
+ }
+ }
return true;
-
}
}
@@ -2039,9 +2046,16 @@ bool GDInstance::get(const StringName& p_name, Variant &r_ret) const {
while(sptr) {
{
- const Map<StringName,int>::Element *E = script->member_indices.find(p_name);
+ const Map<StringName,GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
if (E) {
- r_ret=members[E->get()];
+ if (E->get().getter) {
+ Variant::CallError err;
+ r_ret=const_cast<GDInstance*>(this)->call(E->get().getter,NULL,0,err);
+ if (err.error==Variant::CallError::CALL_OK) {
+ return true;
+ }
+ }
+ r_ret=members[E->get().index];
return true; //index found
}
@@ -2131,7 +2145,7 @@ void GDInstance::get_property_list(List<PropertyInfo> *p_properties) const {
_GDScriptMemberSort ms;
ERR_CONTINUE(!sptr->member_indices.has(E->key()));
- ms.index=sptr->member_indices[E->key()];
+ ms.index=sptr->member_indices[E->key()].index;
ms.name=E->key();
msort.push_back(ms);
@@ -2441,6 +2455,7 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
"false" ,
"tool",
"var",
+ "setget",
"pass",
"and",
"or",
diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h
index 6f0c156d2a..3b183a41b6 100644
--- a/modules/gdscript/gd_script.h
+++ b/modules/gdscript/gd_script.h
@@ -220,11 +220,18 @@ class GDScript : public Script {
bool valid;
+ struct MemberInfo {
+ int index;
+ StringName setter;
+ StringName getter;
+ };
friend class GDInstance;
friend class GDFunction;
friend class GDCompiler;
friend class GDFunctions;
+friend class GDScriptLanguage;
+
Variant _static_ref; //used for static call
Ref<GDNativeClass> native;
Ref<GDScript> base;
@@ -234,7 +241,7 @@ friend class GDFunctions;
Set<StringName> members; //members are just indices to the instanced script.
Map<StringName,Variant> constants;
Map<StringName,GDFunction> member_functions;
- Map<StringName,int> member_indices; //members are just indices to the instanced script.
+ Map<StringName,MemberInfo> member_indices; //members are just indices to the instanced script.
Map<StringName,Ref<GDScript> > subclasses;
#ifdef TOOLS_ENABLED
@@ -288,7 +295,7 @@ public:
bool is_tool() const { return tool; }
Ref<GDScript> get_base() const;
- const Map<StringName,int>& debug_get_member_indices() const { return member_indices; }
+ const Map<StringName,MemberInfo>& debug_get_member_indices() const { return member_indices; }
const Map<StringName,GDFunction>& debug_get_member_functions() const; //this is debug only
StringName debug_get_member_by_index(int p_idx) const;
diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp
index 9ccedd34ea..0fa83b9eb4 100644
--- a/modules/gdscript/gd_tokenizer.cpp
+++ b/modules/gdscript/gd_tokenizer.cpp
@@ -91,6 +91,7 @@ const char* GDTokenizer::token_names[TK_MAX]={
"tool",
"static",
"export",
+"setget",
"const",
"var",
"preload",
@@ -831,6 +832,7 @@ void GDTokenizerText::_advance() {
{TK_PR_TOOL,"tool"},
{TK_PR_STATIC,"static"},
{TK_PR_EXPORT,"export"},
+ {TK_PR_SETGET,"setget"},
{TK_PR_VAR,"var"},
{TK_PR_PRELOAD,"preload"},
{TK_PR_ASSERT,"assert"},
@@ -1015,7 +1017,7 @@ void GDTokenizerText::advance(int p_amount) {
//////////////////////////////////////////////////////////////////////////////////////////////////////
-#define BYTECODE_VERSION 2
+#define BYTECODE_VERSION 3
Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) {
diff --git a/modules/gdscript/gd_tokenizer.h b/modules/gdscript/gd_tokenizer.h
index 1dd538867e..4f9522fb56 100644
--- a/modules/gdscript/gd_tokenizer.h
+++ b/modules/gdscript/gd_tokenizer.h
@@ -98,6 +98,7 @@ public:
TK_PR_TOOL,
TK_PR_STATIC,
TK_PR_EXPORT,
+ TK_PR_SETGET,
TK_PR_CONST,
TK_PR_VAR,
TK_PR_PRELOAD,
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 8b46773502..543eecdf8b 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -121,16 +121,16 @@ static void register_editor_plugin() {
void register_gdscript_types() {
+ ObjectTypeDB::register_type<GDScript>();
+ ObjectTypeDB::register_virtual_type<GDFunctionState>();
script_language_gd=memnew( GDScriptLanguage );
script_language_gd->init();
ScriptServer::register_language(script_language_gd);
- ObjectTypeDB::register_type<GDScript>();
resource_loader_gd=memnew( ResourceFormatLoaderGDScript );
ResourceLoader::add_resource_format_loader(resource_loader_gd);
resource_saver_gd=memnew( ResourceFormatSaverGDScript );
ResourceSaver::add_resource_format_saver(resource_saver_gd);
- ObjectTypeDB::register_virtual_type<GDFunctionState>();
#ifdef TOOLS_ENABLED
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index d258e26a0e..7c10c474c3 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -1041,7 +1041,7 @@ void GridMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_clip","enabled","clipabove","floor","axis"),&GridMap::set_clip,DEFVAL(true),DEFVAL(0),DEFVAL(Vector3::AXIS_X));
- ObjectTypeDB::bind_method(_MD("crate_area","id","area"),&GridMap::create_area);
+ ObjectTypeDB::bind_method(_MD("create_area","id","area"),&GridMap::create_area);
ObjectTypeDB::bind_method(_MD("area_get_bounds","area","bounds"),&GridMap::area_get_bounds);
ObjectTypeDB::bind_method(_MD("area_set_exterior_portal","area","enable"),&GridMap::area_set_exterior_portal);
ObjectTypeDB::bind_method(_MD("area_set_name","area","name"),&GridMap::area_set_name);
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index aef223470a..6bf94b8289 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -184,6 +184,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
String cmdline;
bool _signed;
bool apk_expansion;
+ bool remove_prev;
String apk_expansion_salt;
String apk_expansion_pkey;
int orientation;
@@ -258,7 +259,9 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant&
String n=p_name;
- if (n=="custom_package/debug")
+ if (n=="one_click_deploy/clear_previous_install")
+ remove_prev=p_value;
+ else if (n=="custom_package/debug")
custom_debug_package=p_value;
else if (n=="custom_package/release")
custom_release_package=p_value;
@@ -321,7 +324,9 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant&
bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret) const{
String n=p_name;
- if (n=="custom_package/debug")
+ if (n=="one_click_deploy/clear_previous_install")
+ r_ret=remove_prev;
+ else if (n=="custom_package/debug")
r_ret=custom_debug_package;
else if (n=="custom_package/release")
r_ret=custom_release_package;
@@ -378,6 +383,7 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret)
void EditorExportPlatformAndroid::_get_property_list( List<PropertyInfo> *p_list) const{
+ p_list->push_back( PropertyInfo( Variant::BOOL, "one_click_deploy/clear_previous_install"));
p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE,"apk"));
p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE,"apk"));
p_list->push_back( PropertyInfo( Variant::STRING, "command_line/extra_args"));
@@ -1448,16 +1454,20 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
return err;
}
- ep.step("Uninstalling..",1);
-
- print_line("Uninstalling previous version: "+devices[p_device].name);
List<String> args;
- args.push_back("-s");
- args.push_back(devices[p_device].id);
- args.push_back("uninstall");
- args.push_back(package);
int rv;
- err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
+
+ if (remove_prev) {
+ ep.step("Uninstalling..",1);
+
+ print_line("Uninstalling previous version: "+devices[p_device].name);
+
+ args.push_back("-s");
+ args.push_back(devices[p_device].id);
+ args.push_back("uninstall");
+ args.push_back(package);
+
+ err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
#if 0
if (err || rv!=0) {
EditorNode::add_io_error("Could not install to device.");
@@ -1465,6 +1475,8 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
return ERR_CANT_CREATE;
}
#endif
+ }
+
print_line("Installing into device (please wait..): "+devices[p_device].name);
ep.step("Installing to Device (please wait..)..",2);
@@ -1473,7 +1485,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
args.push_back(devices[p_device].id);
args.push_back("install");
args.push_back(export_to);
- rv;
+
err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
if (err || rv!=0) {
EditorNode::add_io_error("Could not install to device.");
@@ -1515,6 +1527,7 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
device_lock = Mutex::create();
quit_request=false;
orientation=0;
+ remove_prev=false;
device_thread=Thread::create(_device_poll_thread,this);
devices_changed=true;
diff --git a/platform/isim/SCsub b/platform/isim/SCsub
index e7de935b2e..07761486a9 100644
--- a/platform/isim/SCsub
+++ b/platform/isim/SCsub
@@ -34,11 +34,4 @@ if env['ios_appirater'] == "yes":
obj = env_ios.Object('#platform/iphone/godot_iphone.cpp')
prog = None
-if env["target"]=="release":
- prog = env_ios.Program('#bin/godot_opt', [obj] + iphone_lib)
- #action = "dsymutil "+File(prog)[0].path+" -o ../build/script_exec/build/Debug-iphoneos/script_exec.app.dSYM"
- #env.AddPostAction(prog, action)
-else:
- prog = env_ios.Program('#bin/godot', [obj] + iphone_lib)
- #action = "dsymutil "+File(prog)[0].path+" -o ../build/script_exec/build/Debug-iphoneos/script_exec.app.dSYM"
- #env.AddPostAction(prog, action)
+prog = env_ios.Program('#bin/godot', [obj] + iphone_lib)
diff --git a/platform/isim/detect.py b/platform/isim/detect.py
index c89ca81167..f4a17838f9 100644
--- a/platform/isim/detect.py
+++ b/platform/isim/detect.py
@@ -22,7 +22,7 @@ def get_opts():
return [
('ISIMPLATFORM', 'name of the iphone platform', 'iPhoneSimulator'),
('ISIMPATH', 'the path to iphone toolchain', '/Applications/Xcode.app/Contents/Developer/Platforms/${ISIMPLATFORM}.platform'),
- ('ISIMSDK', 'path to the iphone SDK', '$ISIMPATH/Developer/SDKs/${ISIMPLATFORM}7.0.sdk'),
+ ('ISIMSDK', 'path to the iphone SDK', '$ISIMPATH/Developer/SDKs/${ISIMPLATFORM}7.1.sdk'),
('game_center', 'Support for game center', 'yes'),
('store_kit', 'Support for in-app store', 'yes'),
('ios_gles22_override', 'Force GLES2.0 on iOS', 'yes'),
@@ -34,9 +34,7 @@ def get_opts():
def get_flags():
return [
- ('lua', 'no'),
('tools', 'yes'),
- ('nedmalloc', 'no'),
('webp', 'yes'),
]
@@ -46,10 +44,6 @@ def configure(env):
env.Append(CPPPATH=['#platform/iphone'])
- env['OBJSUFFIX'] = ".isim.o"
- env['LIBSUFFIX'] = ".isim.a"
- env['PROGSUFFIX'] = ".isim"
-
env['ENV']['PATH'] = env['ISIMPATH']+"/Developer/usr/bin/:"+env['ENV']['PATH']
env['CC'] = '$ISIMPATH/Developer/usr/bin/gcc'
@@ -83,8 +77,6 @@ def configure(env):
env.Append(CCFLAGS=['-O3', '-ffast-math'])
env.Append(LINKFLAGS=['-O3', '-ffast-math'])
- env['OBJSUFFIX'] = "_opt"+env['OBJSUFFIX']
- env['LIBSUFFIX'] = "_opt"+env['LIBSUFFIX']
elif (env["target"]=="debug"):
@@ -99,8 +91,6 @@ def configure(env):
env['ENV']['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate'
- env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-fno-exceptions'])
+ env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-fexceptions'])
- if env['lua'] == "yes":
- env.Append(CCFLAGS=['-DLUA_USE_FLOAT'])
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 63fb5a47a5..16f70b60d0 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -64,7 +64,7 @@ def get_flags():
return [
('freetype','builtin'), #use builtin freetype
('openssl','builtin'), #use builtin openssl
- ('theora','no'), #use builtin openssl
+ ('theora','no'),
]
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 8616a20486..03de91fa2f 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -54,6 +54,7 @@ def get_flags():
return [
('builtin_zlib', 'no'),
("openssl", "yes"),
+ ("theora","no"),
]
@@ -77,6 +78,10 @@ def configure(env):
if (env["use_sanitizer"]=="yes"):
env.Append(CXXFLAGS=['-fsanitize=address','-fno-omit-frame-pointer'])
env.Append(LINKFLAGS=['-fsanitize=address'])
+ env.extra_suffix=".llvms"
+ else:
+ env.extra_suffix=".llvm"
+
diff --git a/scene/3d/baked_light_instance.cpp b/scene/3d/baked_light_instance.cpp
index c1cc1f6b68..b55093a779 100644
--- a/scene/3d/baked_light_instance.cpp
+++ b/scene/3d/baked_light_instance.cpp
@@ -63,3 +63,81 @@ BakedLightInstance::BakedLightInstance() {
}
+/////////////////////////
+
+
+void BakedLightSampler::set_param(Param p_param,float p_value) {
+ ERR_FAIL_INDEX(p_param,PARAM_MAX);
+ params[p_param]=p_value;
+ VS::get_singleton()->baked_light_sampler_set_param(base,VS::BakedLightSamplerParam(p_param),p_value);
+}
+
+float BakedLightSampler::get_param(Param p_param) const{
+
+ ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
+ return params[p_param];
+
+}
+
+void BakedLightSampler::set_resolution(int p_resolution){
+
+ ERR_FAIL_COND(p_resolution<4 && p_resolution>32);
+ resolution=p_resolution;
+ VS::get_singleton()->baked_light_sampler_set_resolution(base,resolution);
+}
+int BakedLightSampler::get_resolution() const {
+
+ return resolution;
+}
+
+AABB BakedLightSampler::get_aabb() const {
+
+ float r = get_param(PARAM_RADIUS);
+ return AABB( Vector3(-r,-r,-r),Vector3(r*2,r*2,r*2));
+}
+DVector<Face3> BakedLightSampler::get_faces(uint32_t p_usage_flags) const {
+ return DVector<Face3>();
+}
+
+void BakedLightSampler::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_param","param","value"),&BakedLightSampler::set_param);
+ ObjectTypeDB::bind_method(_MD("get_param","param"),&BakedLightSampler::get_param);
+
+ ObjectTypeDB::bind_method(_MD("set_resolution","resolution"),&BakedLightSampler::set_resolution);
+ ObjectTypeDB::bind_method(_MD("get_resolution"),&BakedLightSampler::get_resolution);
+
+
+ BIND_CONSTANT( PARAM_RADIUS );
+ BIND_CONSTANT( PARAM_STRENGTH );
+ BIND_CONSTANT( PARAM_ATTENUATION );
+ BIND_CONSTANT( PARAM_DETAIL_RATIO );
+ BIND_CONSTANT( PARAM_MAX );
+
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/radius",PROPERTY_HINT_RANGE,"0.01,1024,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_RADIUS);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/strength",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_STRENGTH);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/attenuation",PROPERTY_HINT_EXP_EASING),_SCS("set_param"),_SCS("get_param"),PARAM_ATTENUATION);
+ ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/detail_ratio",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),_SCS("set_param"),_SCS("get_param"),PARAM_DETAIL_RATIO);
+// ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/detail_ratio",PROPERTY_HINT_RANGE,"0,20,1"),_SCS("set_param"),_SCS("get_param"),PARAM_DETAIL_RATIO);
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"params/resolution",PROPERTY_HINT_RANGE,"4,32,1"),_SCS("set_resolution"),_SCS("get_resolution"));
+
+}
+
+BakedLightSampler::BakedLightSampler() {
+
+ base = VS::get_singleton()->baked_light_sampler_create();
+ set_base(base);
+
+ params[PARAM_RADIUS]=1.0;
+ params[PARAM_STRENGTH]=1.0;
+ params[PARAM_ATTENUATION]=1.0;
+ params[PARAM_DETAIL_RATIO]=0.1;
+ resolution=16;
+
+
+}
+
+BakedLightSampler::~BakedLightSampler(){
+
+ VS::get_singleton()->free(base);
+}
diff --git a/scene/3d/baked_light_instance.h b/scene/3d/baked_light_instance.h
index b904ced9a7..0694c813ce 100644
--- a/scene/3d/baked_light_instance.h
+++ b/scene/3d/baked_light_instance.h
@@ -30,4 +30,46 @@ public:
BakedLightInstance();
};
+
+
+class BakedLightSampler : public VisualInstance {
+ OBJ_TYPE(BakedLightSampler,VisualInstance);
+
+
+public:
+
+ enum Param {
+ PARAM_RADIUS=VS::BAKED_LIGHT_SAMPLER_RADIUS,
+ PARAM_STRENGTH=VS::BAKED_LIGHT_SAMPLER_STRENGTH,
+ PARAM_ATTENUATION=VS::BAKED_LIGHT_SAMPLER_ATTENUATION,
+ PARAM_DETAIL_RATIO=VS::BAKED_LIGHT_SAMPLER_DETAIL_RATIO,
+ PARAM_MAX=VS::BAKED_LIGHT_SAMPLER_MAX
+ };
+
+
+
+protected:
+
+ RID base;
+ float params[PARAM_MAX];
+ int resolution;
+ static void _bind_methods();
+public:
+
+ virtual AABB get_aabb() const;
+ virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
+
+ void set_param(Param p_param,float p_value);
+ float get_param(Param p_param) const;
+
+ void set_resolution(int p_resolution);
+ int get_resolution() const;
+
+ BakedLightSampler();
+ ~BakedLightSampler();
+};
+
+VARIANT_ENUM_CAST( BakedLightSampler::Param );
+
+
#endif // BAKED_LIGHT_H
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index 93a27f7ac1..ab28c0c8d4 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -467,7 +467,15 @@ Vector3 Camera::project_local_ray_normal(const Point2& p_pos) const {
ERR_FAIL_COND_V(!is_inside_scene(),Vector3());
}
+
+#if 0
Size2 viewport_size = viewport_ptr->get_visible_rect().size;
+ Vector2 cpos = p_pos;
+#else
+
+ Size2 viewport_size = viewport_ptr->get_camera_rect_size();
+ Vector2 cpos = viewport_ptr->get_camera_coords(p_pos);
+#endif
Vector3 ray;
@@ -479,10 +487,9 @@ Vector3 Camera::project_local_ray_normal(const Point2& p_pos) const {
cm.set_perspective(fov,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
float screen_w,screen_h;
cm.get_viewport_size(screen_w,screen_h);
- ray=Vector3( ((p_pos.x/viewport_size.width)*2.0-1.0)*screen_w, ((1.0-(p_pos.y/viewport_size.height))*2.0-1.0)*screen_h,-near).normalized();
+ ray=Vector3( ((cpos.x/viewport_size.width)*2.0-1.0)*screen_w, ((1.0-(cpos.y/viewport_size.height))*2.0-1.0)*screen_h,-near).normalized();
}
-
return ray;
};
@@ -494,8 +501,14 @@ Vector3 Camera::project_ray_origin(const Point2& p_pos) const {
ERR_FAIL_COND_V(!is_inside_scene(),Vector3());
}
+#if 0
Size2 viewport_size = viewport_ptr->get_visible_rect().size;
+ Vector2 cpos = p_pos;
+#else
+ Size2 viewport_size = viewport_ptr->get_camera_rect_size();
+ Vector2 cpos = viewport_ptr->get_camera_coords(p_pos);
+#endif
ERR_FAIL_COND_V( viewport_size.y == 0, Vector3() );
// float aspect = viewport_size.x / viewport_size.y;
@@ -505,7 +518,7 @@ Vector3 Camera::project_ray_origin(const Point2& p_pos) const {
return get_camera_transform().origin;
} else {
- Vector2 pos = p_pos / viewport_size;
+ Vector2 pos = cpos / viewport_size;
float vsize,hsize;
if (keep_aspect==KEEP_WIDTH) {
vsize = size/viewport_size.get_aspect();
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index 858ee4e4ad..737f7d2dce 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -237,6 +237,21 @@ Transform Skeleton::get_bone_transform(int p_bone) const {
return bones[p_bone].pose_global * bones[p_bone].rest_global_inverse;
}
+
+void Skeleton::set_bone_global_pose(int p_bone,const Transform& p_pose) {
+
+ ERR_FAIL_INDEX(p_bone,bones.size());
+ if (bones[p_bone].parent==-1) {
+
+ set_bone_pose(p_bone,bones[p_bone].rest.inverse() * p_pose);
+ } else {
+
+ set_bone_pose(p_bone, bones[p_bone].rest.inverse() * (get_bone_global_pose(bones[p_bone].parent).affine_inverse() * p_pose));
+
+ }
+
+}
+
Transform Skeleton::get_bone_global_pose(int p_bone) const {
ERR_FAIL_INDEX_V(p_bone,bones.size(),Transform());
@@ -519,6 +534,7 @@ void Skeleton::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_bone_pose","bone_idx"),&Skeleton::get_bone_pose);
ObjectTypeDB::bind_method(_MD("set_bone_pose","bone_idx","pose"),&Skeleton::set_bone_pose);
+ ObjectTypeDB::bind_method(_MD("set_bone_global_pose","bone_idx","pose"),&Skeleton::set_bone_global_pose);
ObjectTypeDB::bind_method(_MD("get_bone_global_pose","bone_idx"),&Skeleton::get_bone_global_pose);
ObjectTypeDB::bind_method(_MD("get_bone_custom_pose","bone_idx"),&Skeleton::get_bone_custom_pose);
diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h
index 3e0ab0afd7..c61946a4c7 100644
--- a/scene/3d/skeleton.h
+++ b/scene/3d/skeleton.h
@@ -118,6 +118,8 @@ public:
Transform get_bone_transform(int p_bone) const;
Transform get_bone_global_pose(int p_bone) const;
+ void set_bone_global_pose(int p_bone,const Transform& p_pose);
+
void set_bone_enabled(int p_bone, bool p_enabled);
bool is_bone_enabled(int p_bone) const;
diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp
index af535e139f..398fbdea82 100644
--- a/scene/3d/visual_instance.cpp
+++ b/scene/3d/visual_instance.cpp
@@ -50,17 +50,24 @@ void VisualInstance::_notification(int p_what) {
// CHECK ROOM
Spatial * parent = get_parent_spatial();
Room *room=NULL;
+ bool is_geom = cast_to<GeometryInstance>();
while(parent) {
room = parent->cast_to<Room>();
if (room)
break;
- else
- parent=parent->get_parent_spatial();
+
+ if (is_geom && parent->cast_to<BakedLightSampler>()) {
+ VS::get_singleton()->instance_geometry_set_baked_light_sampler(get_instance(),parent->cast_to<BakedLightSampler>()->get_instance());
+ break;
+ }
+
+ parent=parent->get_parent_spatial();
}
+
if (room) {
VisualServer::get_singleton()->instance_set_room(instance,room->get_instance());
@@ -85,6 +92,7 @@ void VisualInstance::_notification(int p_what) {
VisualServer::get_singleton()->instance_set_scenario( instance, RID() );
VisualServer::get_singleton()->instance_set_room(instance,RID());
VisualServer::get_singleton()->instance_attach_skeleton( instance, RID() );
+ VS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() );
} break;
diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h
index bbb49a2e78..e9fefe1ba0 100644
--- a/scene/3d/visual_instance.h
+++ b/scene/3d/visual_instance.h
@@ -47,6 +47,7 @@ class VisualInstance : public Spatial {
RID _get_visual_instance_rid() const;
+
protected:
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 88fabb3489..9a3c7e71ec 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -927,7 +927,7 @@ void AnimationPlayer::play(const StringName& p_name, float p_custom_blend, float
StringName next=animation_get_next(p_name);
- if (next!=StringName()) {
+ if (next!=StringName() && animation_set.has(next)) {
queue(next);
}
}
diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h
index 63a6468a73..bfa755ff7c 100644
--- a/scene/main/scene_main_loop.h
+++ b/scene/main/scene_main_loop.h
@@ -226,6 +226,9 @@ public:
void set_screen_stretch(StretchMode p_mode,StretchAspect p_aspect,const Size2 p_minsize);
+ //void change_scene(const String& p_path);
+ //Node *get_loaded_scene();
+
#ifdef TOOLS_ENABLED
void set_edited_scene_root(Node *p_node);
Node *get_edited_scene_root() const;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 7e953e44c7..6b7ed66463 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -95,8 +95,8 @@ void Viewport::_update_stretch_transform() {
if (size_override_stretch && size_override) {
- print_line("sive override size "+size_override_size);
- print_line("rect size "+rect.size);
+ //print_line("sive override size "+size_override_size);
+ //print_line("rect size "+rect.size);
stretch_transform=Matrix32();
Size2 scale = rect.size/(size_override_size+size_override_margin*2);
stretch_transform.scale(scale);
@@ -135,7 +135,9 @@ void Viewport::_update_rect() {
}
vr.width=rect.size.width;
vr.height=rect.size.height;
+
VisualServer::get_singleton()->viewport_set_rect(viewport,vr);
+ last_vp_rect=rect;
if (canvas_item.is_valid()) {
VisualServer::get_singleton()->canvas_item_set_custom_rect(canvas_item,true,rect);
@@ -513,6 +515,7 @@ void Viewport::set_rect(const Rect2& p_rect) {
if (rect==p_rect)
return;
rect=p_rect;
+
_update_rect();
_update_stretch_transform();
@@ -1029,13 +1032,16 @@ void Viewport::_make_input_local(InputEvent& ev) {
Matrix32 ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
Vector2 g = ai.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y));
Vector2 l = ai.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y));
- Vector2 r = ai.xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y));
+ Vector2 r = ai.basis_xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y));
+ Vector2 s = ai.basis_xform(Vector2(ev.mouse_motion.speed_x,ev.mouse_motion.speed_y));
ev.mouse_motion.x=l.x;
ev.mouse_motion.y=l.y;
ev.mouse_motion.global_x=g.x;
ev.mouse_motion.global_y=g.y;
ev.mouse_motion.relative_x=r.x;
ev.mouse_motion.relative_y=r.y;
+ ev.mouse_motion.speed_x=s.x;
+ ev.mouse_motion.speed_y=s.y;
} break;
case InputEvent::SCREEN_TOUCH: {
@@ -1050,8 +1056,8 @@ void Viewport::_make_input_local(InputEvent& ev) {
Matrix32 ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
Vector2 t = ai.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y));
- Vector2 r = ai.xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y));
- Vector2 s = ai.xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y));
+ Vector2 r = ai.basis_xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y));
+ Vector2 s = ai.basis_xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y));
ev.screen_drag.x=t.x;
ev.screen_drag.y=t.y;
ev.screen_drag.relative_x=r.x;
@@ -1185,6 +1191,21 @@ void Viewport::set_physics_object_picking(bool p_enable) {
}
+
+Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const {
+
+ Matrix32 xf = get_final_transform();
+ return xf.xform(p_viewport_coords);
+
+
+}
+
+Vector2 Viewport::get_camera_rect_size() const {
+
+ return last_vp_rect.size;
+}
+
+
bool Viewport::get_physics_object_picking() {
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 5d68438f0d..37f1b357c6 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -110,6 +110,7 @@ friend class RenderTargetTexture;
Size2 size_override_size;
Size2 size_override_margin;
+ Rect2 last_vp_rect;
bool transparent_bg;
bool render_target_vflip;
@@ -229,6 +230,10 @@ public:
RenderTargetUpdateMode get_render_target_update_mode() const;
Ref<RenderTargetTexture> get_render_target_texture() const;
+
+ Vector2 get_camera_coords(const Vector2& p_viewport_coords) const;
+ Vector2 get_camera_rect_size() const;
+
void queue_screen_capture();
Image get_screen_capture() const;
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index afa127caef..f3b13f30bf 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -394,6 +394,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<VisibilityNotifier>();
ObjectTypeDB::register_type<VisibilityEnabler>();
ObjectTypeDB::register_type<BakedLightInstance>();
+ ObjectTypeDB::register_type<BakedLightSampler>();
ObjectTypeDB::register_type<WorldEnvironment>();
//scenariofx
diff --git a/scene/resources/baked_light.cpp b/scene/resources/baked_light.cpp
index 647c8df5d4..226edec9ae 100644
--- a/scene/resources/baked_light.cpp
+++ b/scene/resources/baked_light.cpp
@@ -23,6 +23,27 @@ DVector<uint8_t> BakedLight::get_octree() const {
return VS::get_singleton()->baked_light_get_octree(baked_light);
}
+void BakedLight::set_light(const DVector<uint8_t>& p_light) {
+
+ VS::get_singleton()->baked_light_set_light(baked_light,p_light);
+}
+
+DVector<uint8_t> BakedLight::get_light() const {
+
+ return VS::get_singleton()->baked_light_get_light(baked_light);
+}
+
+
+void BakedLight::set_sampler_octree(const DVector<int>& p_sampler_octree) {
+
+ VS::get_singleton()->baked_light_set_sampler_octree(baked_light,p_sampler_octree);
+}
+
+DVector<int> BakedLight::get_sampler_octree() const {
+
+ return VS::get_singleton()->baked_light_get_sampler_octree(baked_light);
+}
+
@@ -199,6 +220,43 @@ float BakedLight::get_normal_damp() const {
return normal_damp;
}
+void BakedLight::set_tint(float p_margin) {
+ tint=p_margin;
+}
+
+float BakedLight::get_tint() const {
+
+ return tint;
+}
+
+void BakedLight::set_saturation(float p_margin) {
+ saturation=p_margin;
+}
+
+float BakedLight::get_saturation() const {
+
+ return saturation;
+}
+
+void BakedLight::set_ao_radius(float p_ao_radius) {
+ ao_radius=p_ao_radius;
+}
+
+float BakedLight::get_ao_radius() const {
+ return ao_radius;
+}
+
+void BakedLight::set_ao_strength(float p_ao_strength) {
+
+ ao_strength=p_ao_strength;
+}
+
+float BakedLight::get_ao_strength() const {
+
+ return ao_strength;
+}
+
+
void BakedLight::set_energy_multiplier(float p_multiplier){
energy_multiply=p_multiplier;
@@ -329,6 +387,13 @@ void BakedLight::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_octree","octree"),&BakedLight::set_octree);
ObjectTypeDB::bind_method(_MD("get_octree"),&BakedLight::get_octree);
+ ObjectTypeDB::bind_method(_MD("set_light","light"),&BakedLight::set_light);
+ ObjectTypeDB::bind_method(_MD("get_light"),&BakedLight::get_light);
+
+ ObjectTypeDB::bind_method(_MD("set_sampler_octree","sampler_octree"),&BakedLight::set_sampler_octree);
+ ObjectTypeDB::bind_method(_MD("get_sampler_octree"),&BakedLight::get_sampler_octree);
+
+
ObjectTypeDB::bind_method(_MD("add_lightmap","texture:Texture","gen_size"),&BakedLight::add_lightmap);
ObjectTypeDB::bind_method(_MD("erase_lightmap","id"),&BakedLight::erase_lightmap);
ObjectTypeDB::bind_method(_MD("clear_lightmaps"),&BakedLight::clear_lightmaps);
@@ -357,6 +422,18 @@ void BakedLight::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_normal_damp","normal_damp"),&BakedLight::set_normal_damp);
ObjectTypeDB::bind_method(_MD("get_normal_damp"),&BakedLight::get_normal_damp);
+ ObjectTypeDB::bind_method(_MD("set_tint","tint"),&BakedLight::set_tint);
+ ObjectTypeDB::bind_method(_MD("get_tint"),&BakedLight::get_tint);
+
+ ObjectTypeDB::bind_method(_MD("set_saturation","saturation"),&BakedLight::set_saturation);
+ ObjectTypeDB::bind_method(_MD("get_saturation"),&BakedLight::get_saturation);
+
+ ObjectTypeDB::bind_method(_MD("set_ao_radius","ao_radius"),&BakedLight::set_ao_radius);
+ ObjectTypeDB::bind_method(_MD("get_ao_radius"),&BakedLight::get_ao_radius);
+
+ ObjectTypeDB::bind_method(_MD("set_ao_strength","ao_strength"),&BakedLight::set_ao_strength);
+ ObjectTypeDB::bind_method(_MD("get_ao_strength"),&BakedLight::get_ao_strength);
+
ObjectTypeDB::bind_method(_MD("set_format","format"),&BakedLight::set_format);
ObjectTypeDB::bind_method(_MD("get_format"),&BakedLight::get_format);
@@ -384,17 +461,24 @@ void BakedLight::_bind_methods(){
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/plot_size",PROPERTY_HINT_RANGE,"1.0,16.0,0.01"),_SCS("set_plot_size"),_SCS("get_plot_size"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/energy_mult",PROPERTY_HINT_RANGE,"0.01,4096.0,0.01"),_SCS("set_energy_multiplier"),_SCS("get_energy_multiplier"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/gamma_adjust",PROPERTY_HINT_EXP_EASING),_SCS("set_gamma_adjust"),_SCS("get_gamma_adjust"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/saturation",PROPERTY_HINT_RANGE,"0,8,0.01"),_SCS("set_saturation"),_SCS("get_saturation"));
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/diffuse"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_DIFFUSE);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/specular"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_SPECULAR);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/translucent"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_TRANSLUCENT);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/conserve_energy"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_CONSERVE_ENERGY);
+ ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/linear_color"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_LINEAR_COLOR);
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"lightmap/use_only_uv2"),_SCS("set_transfer_lightmaps_only_to_uv2"),_SCS("get_transfer_lightmaps_only_to_uv2"));
ADD_PROPERTY( PropertyInfo(Variant::RAW_ARRAY,"octree",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_octree"),_SCS("get_octree"));
+ ADD_PROPERTY( PropertyInfo(Variant::RAW_ARRAY,"light",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_light"),_SCS("get_light"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT_ARRAY,"sampler_octree",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_sampler_octree"),_SCS("get_sampler_octree"));
ADD_PROPERTY( PropertyInfo(Variant::ARRAY,"lightmaps",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_lightmap_data"),_SCS("_get_lightmap_data"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/cell_margin",PROPERTY_HINT_RANGE,"0.01,0.8,0.01"),_SCS("set_cell_extra_margin"),_SCS("get_cell_extra_margin"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/edge_damp",PROPERTY_HINT_RANGE,"0.0,8.0,0.1"),_SCS("set_edge_damp"),_SCS("get_edge_damp"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/normal_damp",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_normal_damp"),_SCS("get_normal_damp"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/light_tint",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_tint"),_SCS("get_tint"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/ao_radius",PROPERTY_HINT_RANGE,"0.0,16.0,0.01"),_SCS("set_ao_radius"),_SCS("get_ao_radius"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/ao_strength",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_ao_strength"),_SCS("get_ao_strength"));
BIND_CONSTANT( MODE_OCTREE );
BIND_CONSTANT( MODE_LIGHTMAPS );
@@ -415,18 +499,24 @@ BakedLight::BakedLight() {
lattice_subdiv=4;
plot_size=2.5;
bounces=1;
- energy_multiply=1.0;
- gamma_adjust=1.0;
+ energy_multiply=2.0;
+ gamma_adjust=0.7;
cell_extra_margin=0.05;
edge_damp=0.0;
normal_damp=0.0;
+ saturation=1;
+ tint=0.0;
+ ao_radius=2.5;
+ ao_strength=0.7;
format=FORMAT_RGB;
transfer_only_uv2=false;
+
flags[BAKE_DIFFUSE]=true;
flags[BAKE_SPECULAR]=false;
flags[BAKE_TRANSLUCENT]=true;
flags[BAKE_CONSERVE_ENERGY]=false;
+ flags[BAKE_LINEAR_COLOR]=false;
mode=MODE_OCTREE;
baked_light=VS::get_singleton()->baked_light_create();
diff --git a/scene/resources/baked_light.h b/scene/resources/baked_light.h
index 57ed7d7aee..41e1e5f9e0 100644
--- a/scene/resources/baked_light.h
+++ b/scene/resources/baked_light.h
@@ -26,6 +26,7 @@ public:
BAKE_SPECULAR,
BAKE_TRANSLUCENT,
BAKE_CONSERVE_ENERGY,
+ BAKE_LINEAR_COLOR,
BAKE_MAX
};
@@ -50,6 +51,10 @@ private:
float cell_extra_margin;
float edge_damp;
float normal_damp;
+ float tint;
+ float ao_radius;
+ float ao_strength;
+ float saturation;
int bounces;
bool transfer_only_uv2;
Format format;
@@ -99,6 +104,18 @@ public:
void set_normal_damp(float p_margin);
float get_normal_damp() const;
+ void set_tint(float p_margin);
+ float get_tint() const;
+
+ void set_saturation(float p_saturation);
+ float get_saturation() const;
+
+ void set_ao_radius(float p_ao_radius);
+ float get_ao_radius() const;
+
+ void set_ao_strength(float p_ao_strength);
+ float get_ao_strength() const;
+
void set_bake_flag(BakeFlags p_flags,bool p_enable);
bool get_bake_flag(BakeFlags p_flags) const;
@@ -114,6 +131,14 @@ public:
void set_octree(const DVector<uint8_t>& p_octree);
DVector<uint8_t> get_octree() const;
+ void set_light(const DVector<uint8_t>& p_light);
+ DVector<uint8_t> get_light() const;
+
+ void set_sampler_octree(const DVector<int>& p_sampler_octree);
+ DVector<int> get_sampler_octree() const;
+
+
+
void add_lightmap(const Ref<Texture> &p_texture,Size2 p_gen_size=Size2(256,256));
void set_lightmap_gen_size(int p_idx,const Size2& p_size);
Size2 get_lightmap_gen_size(int p_idx) const;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 351d65654d..2c278f4fed 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -550,6 +550,10 @@ void ShaderMaterial::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_shader","shader:Shader"), &ShaderMaterial::set_shader );
ObjectTypeDB::bind_method(_MD("get_shader:Shader"), &ShaderMaterial::get_shader );
+
+ ObjectTypeDB::bind_method(_MD("set_shader_param","param","value:var"), &ShaderMaterial::set_shader_param);
+ ObjectTypeDB::bind_method(_MD("get_shader_param:var","param"), &ShaderMaterial::get_shader_param);
+
ObjectTypeDB::bind_method(_MD("_shader_changed"), &ShaderMaterial::_shader_changed );
}
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index dc970383b6..55625a2218 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -503,6 +503,7 @@ public:
VS::BakedLightMode mode;
RID octree_texture;
+ RID light_texture;
float color_multiplier; //used for both lightmaps and octree
Transform octree_transform;
Map<int,RID> lightmaps;
@@ -514,6 +515,7 @@ public:
float lightmap_multiplier;
int octree_steps;
Vector2 octree_tex_pixel_size;
+ Vector2 light_tex_pixel_size;
};
struct InstanceData {
@@ -521,6 +523,7 @@ public:
Transform transform;
RID skeleton;
RID material_override;
+ RID sampled_light;
Vector<RID> light_instances;
Vector<float> morph_values;
BakedLightData *baked_light;
@@ -586,6 +589,10 @@ public:
virtual void environment_fx_set_param(RID p_env,VS::EnvironmentFxParam p_param,const Variant& p_value)=0;
virtual Variant environment_fx_get_param(RID p_env,VS::EnvironmentFxParam p_param) const=0;
+ /* SAMPLED LIGHT */
+ virtual RID sampled_light_dp_create(int p_width,int p_height)=0;
+ virtual void sampled_light_dp_update(RID p_sampled_light,const Color *p_data,float p_multiplier)=0;
+
/*MISC*/
diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp
index 637c251cf1..a671821e25 100644
--- a/servers/visual/rasterizer_dummy.cpp
+++ b/servers/visual/rasterizer_dummy.cpp
@@ -1679,6 +1679,18 @@ Variant RasterizerDummy::environment_fx_get_param(RID p_env,VS::EnvironmentFxPar
}
+
+RID RasterizerDummy::sampled_light_dp_create(int p_width,int p_height) {
+
+ return sampled_light_owner.make_rid(memnew(SampledLight));
+}
+
+void RasterizerDummy::sampled_light_dp_update(RID p_sampled_light, const Color *p_data, float p_multiplier) {
+
+
+}
+
+
/*MISC*/
bool RasterizerDummy::is_texture(const RID& p_rid) const {
@@ -1816,6 +1828,14 @@ void RasterizerDummy::free(const RID& p_rid) {
Environment *env = environment_owner.get( p_rid );
environment_owner.free(p_rid);
memdelete( env );
+ } else if (sampled_light_owner.owns(p_rid)) {
+
+ SampledLight *sampled_light = sampled_light_owner.get( p_rid );
+ ERR_FAIL_COND(!sampled_light);
+
+ sampled_light_owner.free(p_rid);
+ memdelete( sampled_light );
+
};
}
diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h
index 373564249e..44bca423a4 100644
--- a/servers/visual/rasterizer_dummy.h
+++ b/servers/visual/rasterizer_dummy.h
@@ -353,6 +353,13 @@ class RasterizerDummy : public Rasterizer {
mutable RID_Owner<Environment> environment_owner;
+ struct SampledLight {
+
+ int w,h;
+ };
+
+ mutable RID_Owner<SampledLight> sampled_light_owner;
+
struct ShadowBuffer;
struct LightInstance {
@@ -713,6 +720,10 @@ public:
virtual void environment_fx_set_param(RID p_env,VS::EnvironmentFxParam p_param,const Variant& p_value);
virtual Variant environment_fx_get_param(RID p_env,VS::EnvironmentFxParam p_param) const;
+ /* SAMPLED LIGHT */
+ virtual RID sampled_light_dp_create(int p_width,int p_height);
+ virtual void sampled_light_dp_update(RID p_sampled_light,const Color *p_data,float p_multiplier);
+
/*MISC*/
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 8250e4c08f..13ecd49b68 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -1109,8 +1109,12 @@ void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector<
int tex_w;
int tex_h;
+ int light_tex_w;
+ int light_tex_h;
bool is16;
+ bool has_light_tex=false;
{
+
DVector<uint8_t>::Read r=p_octree.read();
tex_w = decode_uint32(&r[0]);
tex_h = decode_uint32(&r[4]);
@@ -1123,7 +1127,22 @@ void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector<
baked_light->data.octree_steps=decode_uint32(&r[16]);
baked_light->data.octree_tex_pixel_size.x=1.0/tex_w;
baked_light->data.octree_tex_pixel_size.y=1.0/tex_h;
+
baked_light->data.texture_multiplier=decode_uint32(&r[20]);
+ light_tex_w=decode_uint16(&r[24]);
+ light_tex_h=decode_uint16(&r[26]);
+ print_line("ltexw "+itos(light_tex_w));
+ print_line("ltexh "+itos(light_tex_h));
+
+ if (light_tex_w>0 && light_tex_h>0) {
+ baked_light->data.light_tex_pixel_size.x=1.0/light_tex_w;
+ baked_light->data.light_tex_pixel_size.y=1.0/light_tex_h;
+ has_light_tex=true;
+ } else {
+ baked_light->data.light_tex_pixel_size=baked_light->data.octree_tex_pixel_size;
+
+ }
+
baked_light->octree_aabb.pos.x=decode_float(&r[32]);
@@ -1141,12 +1160,33 @@ void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector<
rasterizer->free(baked_light->data.octree_texture);
baked_light->data.octree_texture=RID();
+ baked_light->octree_tex_size.x=0;
+ baked_light->octree_tex_size.y=0;
+ }
+ }
+
+ if (baked_light->data.light_texture.is_valid()) {
+ if (!has_light_tex || light_tex_w!=baked_light->light_tex_size.x || light_tex_h!=baked_light->light_tex_size.y) {
+ rasterizer->free(baked_light->data.light_texture);
+ baked_light->data.light_texture=RID();
+ baked_light->light_tex_size.x=0;
+ baked_light->light_tex_size.y=0;
}
}
if (!baked_light->data.octree_texture.is_valid()) {
baked_light->data.octree_texture=rasterizer->texture_create();
rasterizer->texture_allocate(baked_light->data.octree_texture,tex_w,tex_h,Image::FORMAT_RGBA,TEXTURE_FLAG_FILTER);
+ baked_light->octree_tex_size.x=tex_w;
+ baked_light->octree_tex_size.y=tex_h;
+ }
+
+ if (!baked_light->data.light_texture.is_valid() && has_light_tex) {
+ baked_light->data.light_texture=rasterizer->texture_create();
+ rasterizer->texture_allocate(baked_light->data.light_texture,light_tex_w,light_tex_h,Image::FORMAT_RGBA,TEXTURE_FLAG_FILTER);
+ baked_light->light_tex_size.x=light_tex_w;
+ baked_light->light_tex_size.y=light_tex_h;
+
}
Image img(tex_w,tex_h,0,Image::FORMAT_RGBA,p_octree);
@@ -1159,6 +1199,7 @@ void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector<
}
+
DVector<uint8_t> VisualServerRaster::baked_light_get_octree(RID p_baked_light) const{
@@ -1174,6 +1215,67 @@ DVector<uint8_t> VisualServerRaster::baked_light_get_octree(RID p_baked_light) c
}
}
+void VisualServerRaster::baked_light_set_light(RID p_baked_light,const DVector<uint8_t> p_light) {
+
+ VS_CHANGED;
+ BakedLight *baked_light = baked_light_owner.get(p_baked_light);
+ ERR_FAIL_COND(!baked_light);
+ ERR_FAIL_COND(p_light.size()==0);
+
+ int tex_w=baked_light->light_tex_size.x;
+ int tex_h=baked_light->light_tex_size.y;
+
+ ERR_FAIL_COND(tex_w==0 && tex_h==0);
+ ERR_FAIL_COND(!baked_light->data.light_texture.is_valid());
+
+
+
+ print_line("w: "+itos(tex_w)+" h: "+itos(tex_h)+" lightsize: "+itos(p_light.size()));
+
+ Image img(tex_w,tex_h,0,Image::FORMAT_RGBA,p_light);
+ rasterizer->texture_set_data(baked_light->data.light_texture,img);
+
+
+
+}
+
+DVector<uint8_t> VisualServerRaster::baked_light_get_light(RID p_baked_light) const{
+
+ BakedLight *baked_light = baked_light_owner.get(p_baked_light);
+ ERR_FAIL_COND_V(!baked_light,DVector<uint8_t>());
+
+ if (rasterizer->is_texture(baked_light->data.light_texture)) {
+
+ Image img = rasterizer->texture_get_data(baked_light->data.light_texture);
+ return img.get_data();
+ } else {
+ return DVector<uint8_t>();
+ }
+}
+
+
+
+void VisualServerRaster::baked_light_set_sampler_octree(RID p_baked_light, const DVector<int> &p_sampler) {
+
+ BakedLight *baked_light = baked_light_owner.get(p_baked_light);
+ ERR_FAIL_COND(!baked_light);
+
+ baked_light->sampler=p_sampler;
+
+
+
+}
+
+DVector<int> VisualServerRaster::baked_light_get_sampler_octree(RID p_baked_light) const {
+
+ BakedLight *baked_light = baked_light_owner.get(p_baked_light);
+ ERR_FAIL_COND_V(!baked_light,DVector<int>());
+
+ return baked_light->sampler;
+
+}
+
+
void VisualServerRaster::baked_light_add_lightmap(RID p_baked_light,const RID p_texture,int p_id){
VS_CHANGED;
@@ -1192,6 +1294,84 @@ void VisualServerRaster::baked_light_clear_lightmaps(RID p_baked_light){
}
+/* BAKED LIGHT SAMPLER */
+
+RID VisualServerRaster::baked_light_sampler_create() {
+
+ BakedLightSampler * blsamp = memnew( BakedLightSampler );
+ RID rid = baked_light_sampler_owner.make_rid(blsamp);
+ _update_baked_light_sampler_dp_cache(blsamp);
+ return rid;
+}
+
+void VisualServerRaster::baked_light_sampler_set_param(RID p_baked_light_sampler,BakedLightSamplerParam p_param,float p_value){
+
+ VS_CHANGED;
+ BakedLightSampler * blsamp = baked_light_sampler_owner.get(p_baked_light_sampler);
+ ERR_FAIL_COND(!blsamp);
+ ERR_FAIL_INDEX(p_param,BAKED_LIGHT_SAMPLER_MAX);
+ blsamp->params[p_param]=p_value;
+ _dependency_queue_update(p_baked_light_sampler,true);
+}
+
+float VisualServerRaster::baked_light_sampler_get_param(RID p_baked_light_sampler,BakedLightSamplerParam p_param) const{
+
+
+ BakedLightSampler * blsamp = baked_light_sampler_owner.get(p_baked_light_sampler);
+ ERR_FAIL_COND_V(!blsamp,0);
+ ERR_FAIL_INDEX_V(p_param,BAKED_LIGHT_SAMPLER_MAX,0);
+ return blsamp->params[p_param];
+}
+
+void VisualServerRaster::_update_baked_light_sampler_dp_cache(BakedLightSampler * blsamp) {
+
+ int res = blsamp->resolution;
+ blsamp->dp_cache.resize(res*res*2);
+ Vector3 *dp_normals=blsamp->dp_cache.ptr();
+
+ for(int p=0;p<2;p++) {
+ float sign = p==0?1:-1;
+ int ofs = res*res*p;
+ for(int i=0;i<res;i++) {
+ for(int j=0;j<res;j++) {
+
+ Vector2 v(
+ (i/float(res))*2.0-1.0,
+ (j/float(res))*2.0-1.0
+ );
+
+ float l=v.length();
+ if (l>1.0) {
+ v/=l;
+ l=1.0; //clamp to avoid imaginary
+ }
+ v*=(2*l)/(l*l+1); //inverse of the dual paraboloid function
+ Vector3 n = Vector3(v.x,v.y,sign*sqrtf(MAX(1 - v.dot(v),0))); //reconstruction of z
+ n.y*=sign;
+ dp_normals[j*res+i+ofs]=n;
+ }
+ }
+ }
+
+}
+
+void VisualServerRaster::baked_light_sampler_set_resolution(RID p_baked_light_sampler,int p_resolution){
+
+ ERR_FAIL_COND(p_resolution<4 && p_resolution>64);
+ VS_CHANGED;
+ BakedLightSampler * blsamp = baked_light_sampler_owner.get(p_baked_light_sampler);
+ ERR_FAIL_COND(!blsamp);
+ blsamp->resolution=p_resolution;
+ _update_baked_light_sampler_dp_cache(blsamp);
+
+}
+int VisualServerRaster::baked_light_sampler_get_resolution(RID p_baked_light_sampler) const{
+
+ BakedLightSampler * blsamp = baked_light_sampler_owner.get(p_baked_light_sampler);
+ ERR_FAIL_COND_V(!blsamp,0);
+ return blsamp->resolution;
+}
+
/* CAMERA API */
RID VisualServerRaster::camera_create() {
@@ -1943,6 +2123,20 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) {
}
+ if (instance->baked_light_sampler_info) {
+
+ while (instance->baked_light_sampler_info->owned_instances.size()) {
+
+ instance_geometry_set_baked_light_sampler(instance->baked_light_sampler_info->owned_instances.front()->get()->self,RID());
+ }
+
+ if (instance->baked_light_sampler_info->sampled_light.is_valid()) {
+ rasterizer->free(instance->baked_light_sampler_info->sampled_light);
+ }
+ memdelete( instance->baked_light_sampler_info );
+ instance->baked_light_sampler_info=NULL;
+ }
+
instance->data.morph_values.clear();
}
@@ -1992,6 +2186,16 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) {
//instance->portal_info = memnew(Instance::PortalInfo);
//instance->portal_info->portal=portal_owner.get(p_base);
+ } else if (baked_light_sampler_owner.owns(p_base)) {
+
+
+ instance->base_type=INSTANCE_BAKED_LIGHT_SAMPLER;
+ instance->baked_light_sampler_info=memnew( Instance::BakedLightSamplerInfo);
+ instance->baked_light_sampler_info->sampler=baked_light_sampler_owner.get(p_base);
+
+ //instance->portal_info = memnew(Instance::PortalInfo);
+ //instance->portal_info->portal=portal_owner.get(p_base);
+
} else {
ERR_EXPLAIN("Invalid base RID for instance!")
ERR_FAIL();
@@ -2607,11 +2811,50 @@ RID VisualServerRaster::instance_geometry_get_baked_light(RID p_instance) const{
const Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND_V( !instance,RID() );
if (instance->baked_light)
- instance->baked_light->self;
+ return instance->baked_light->self;
return RID();
}
+
+void VisualServerRaster::instance_geometry_set_baked_light_sampler(RID p_instance,RID p_baked_light_sampler) {
+
+ VS_CHANGED;
+ Instance *instance = instance_owner.get( p_instance );
+ ERR_FAIL_COND( !instance );
+
+ if (instance->sampled_light) {
+ instance->sampled_light->baked_light_sampler_info->owned_instances.erase(instance);
+ instance->data.sampled_light=RID();
+ }
+
+ if(p_baked_light_sampler.is_valid()) {
+ Instance *sampler_instance = instance_owner.get( p_baked_light_sampler );
+ ERR_FAIL_COND( !sampler_instance );
+ ERR_FAIL_COND( sampler_instance->base_type!=INSTANCE_BAKED_LIGHT_SAMPLER );
+ instance->sampled_light=sampler_instance;
+ instance->sampled_light->baked_light_sampler_info->owned_instances.insert(instance);
+ } else {
+ instance->sampled_light=NULL;
+ }
+
+ instance->data.sampled_light=RID();
+
+}
+
+RID VisualServerRaster::instance_geometry_get_baked_light_sampler(RID p_instance) const {
+
+ Instance *instance = instance_owner.get( p_instance );
+ ERR_FAIL_COND_V( !instance,RID() );
+
+ if (instance->sampled_light)
+ return instance->sampled_light->self;
+ else
+ return RID();
+
+}
+
+
void VisualServerRaster::instance_geometry_set_baked_light_texture_index(RID p_instance,int p_tex_id){
VS_CHANGED;
@@ -2747,6 +2990,13 @@ void VisualServerRaster::_update_instance(Instance *p_instance) {
pairable=true;
}
+ if (p_instance->base_type == INSTANCE_BAKED_LIGHT_SAMPLER) {
+
+ pairable_mask=(1<<INSTANCE_BAKED_LIGHT);
+ pairable=true;
+ }
+
+
if (!p_instance->room && (1<<p_instance->base_type)&INSTANCE_GEOMETRY_MASK) {
base_type|=INSTANCE_ROOMLESS_MASK;
@@ -2859,6 +3109,16 @@ void VisualServerRaster::_update_instance_aabb(Instance *p_instance) {
new_aabb=baked_light->octree_aabb;
} break;
+ case VisualServer::INSTANCE_BAKED_LIGHT_SAMPLER: {
+
+ BakedLightSampler *baked_light_sampler = baked_light_sampler_owner.get( p_instance->base_rid );
+ ERR_FAIL_COND(!baked_light_sampler);
+ float radius = baked_light_sampler->params[VS::BAKED_LIGHT_SAMPLER_RADIUS];
+
+ new_aabb=AABB(Vector3(-radius,-radius,-radius),Vector3(radius*2,radius*2,radius*2));
+
+ } break;
+
default: {}
}
@@ -3762,6 +4022,17 @@ void VisualServerRaster::free( RID p_rid ) {
baked_light_owner.free(p_rid);
memdelete(baked_light);
+ } else if (baked_light_sampler_owner.owns(p_rid)) {
+
+ _free_attached_instances(p_rid);
+
+ BakedLightSampler *baked_light_sampler = baked_light_sampler_owner.get(p_rid);
+ ERR_FAIL_COND(!baked_light_sampler);
+ //if (baked_light->data.octree_texture.is_valid())
+ // rasterizer->free(baked_light->data.octree_texture);
+ baked_light_sampler_owner.free(p_rid);
+ memdelete(baked_light_sampler);
+
} else if (camera_owner.owns(p_rid)) {
// delete te camera
@@ -3813,7 +4084,9 @@ void VisualServerRaster::free( RID p_rid ) {
instance_set_room(p_rid,RID());
instance_set_scenario(p_rid,RID());
instance_geometry_set_baked_light(p_rid,RID());
+ instance_geometry_set_baked_light_sampler(p_rid,RID());
instance_set_base(p_rid,RID());
+
if (instance->data.skeleton.is_valid())
instance_attach_skeleton(p_rid,RID());
@@ -4957,6 +5230,15 @@ void* VisualServerRaster::instance_pair(void *p_self, OctreeElementID, Instance
//attempt to conncet portal A (will go through B anyway)
//this is a little hackish, but works fine in practice
+ } else if (A->base_type==INSTANCE_BAKED_LIGHT || B->base_type==INSTANCE_BAKED_LIGHT) {
+
+ if (B->base_type==INSTANCE_BAKED_LIGHT) {
+ SWAP(A,B);
+ }
+
+ ERR_FAIL_COND_V(B->base_type!=INSTANCE_BAKED_LIGHT_SAMPLER,NULL);
+ B->baked_light_sampler_info->baked_lights.insert(A);
+
} else if (A->base_type==INSTANCE_ROOM || B->base_type==INSTANCE_ROOM) {
if (B->base_type==INSTANCE_ROOM)
@@ -5006,6 +5288,15 @@ void VisualServerRaster::instance_unpair(void *p_self, OctreeElementID, Instance
self->_portal_attempt_connect(A);
self->_portal_attempt_connect(B);
+ } else if (A->base_type==INSTANCE_BAKED_LIGHT || B->base_type==INSTANCE_BAKED_LIGHT) {
+
+ if (B->base_type==INSTANCE_BAKED_LIGHT) {
+ SWAP(A,B);
+ }
+
+ ERR_FAIL_COND(B->base_type!=INSTANCE_BAKED_LIGHT_SAMPLER);
+ B->baked_light_sampler_info->baked_lights.erase(A);
+
} else if (A->base_type==INSTANCE_ROOM || B->base_type==INSTANCE_ROOM) {
if (B->base_type==INSTANCE_ROOM)
@@ -5197,6 +5488,308 @@ void VisualServerRaster::_cull_room(Camera *p_camera, Instance *p_room,Instance
}
+void VisualServerRaster::_process_sampled_light(const Transform& p_camera,Instance *p_sampled_light,bool p_linear_colorspace) {
+
+
+ BakedLightSampler *sampler_opts = p_sampled_light->baked_light_sampler_info->sampler;
+ int res = sampler_opts->resolution;
+ int dp_size = res*res*2;
+ Color * dp_map = (Color*)alloca( sizeof(Color)*dp_size); //allocate the dual parabolloid colors
+ Vector3 * dp_normals = (Vector3*)alloca( sizeof(Vector3)*dp_size); //allocate the dual parabolloid normals
+ const Vector3 * dp_src_normals = p_sampled_light->baked_light_sampler_info->sampler->dp_cache.ptr();
+
+
+ if (!p_sampled_light->baked_light_sampler_info->sampled_light.is_valid() || p_sampled_light->baked_light_sampler_info->resolution!=sampler_opts->resolution) {
+ if (p_sampled_light->baked_light_sampler_info->sampled_light.is_valid()) {
+ rasterizer->free(p_sampled_light->baked_light_sampler_info->sampled_light);
+ }
+
+ p_sampled_light->baked_light_sampler_info->resolution=sampler_opts->resolution;
+ p_sampled_light->baked_light_sampler_info->sampled_light=rasterizer->sampled_light_dp_create(sampler_opts->resolution,sampler_opts->resolution*2);
+
+
+ }
+
+
+ zeromem(dp_map,sizeof(Color)*dp_size);
+ bool valid=false;
+ int samples=0;
+
+
+ for(Set<Instance*>::Element *E=p_sampled_light->baked_light_sampler_info->baked_lights.front();E;E=E->next()) {
+
+ Instance *bl = E->get();
+ if (bl->baked_light_info->baked_light->sampler.size()==0)
+ continue; //not usable
+
+
+ Matrix3 norm_xform = bl->baked_light_info->affine_inverse.basis;//.inverse();
+ for(int i=0;i<dp_size;i++) {
+ dp_normals[i]=norm_xform.xform(dp_src_normals[i]).normalized();
+ }
+
+ //normals in place
+
+
+ //sample octree
+
+ float r = sampler_opts->params[VS::BAKED_LIGHT_SAMPLER_RADIUS];
+ float att = sampler_opts->params[VS::BAKED_LIGHT_SAMPLER_ATTENUATION];
+ float str = sampler_opts->params[VS::BAKED_LIGHT_SAMPLER_STRENGTH];
+ Vector3 s = p_sampled_light->data.transform.basis.get_scale();
+
+ r*=MAX(MAX(s.x,s.y),s.z);
+ AABB sample_aabb= bl->data.transform.affine_inverse().xform(AABB(Vector3(-r,-r,-r)+p_sampled_light->data.transform.origin,Vector3(r*2,r*2,r*2)));
+ //ok got octree local AABB
+
+ DVector<int>::Read rp = bl->baked_light_info->baked_light->sampler.read();
+ const int *rptr = rp.ptr();
+
+ int first = rptr[1];
+ int depth = rptr[2];
+ bool islinear = rptr[3]&1;
+ depth+=1;
+
+ AABB aabb;
+ aabb.pos.x=decode_float((const uint8_t*)&rptr[4]);
+ aabb.pos.y=decode_float((const uint8_t*)&rptr[5]);
+ aabb.pos.z=decode_float((const uint8_t*)&rptr[6]);
+ aabb.size.x=decode_float((const uint8_t*)&rptr[7]);
+ aabb.size.y=decode_float((const uint8_t*)&rptr[8]);
+ aabb.size.z=decode_float((const uint8_t*)&rptr[9]);
+
+ uint32_t *stack=(uint32_t*)alloca(depth*sizeof(uint32_t));
+ int *stack_ptr=(int*)alloca(depth*sizeof(int));
+ AABB *aabb_stack=(AABB*)alloca(depth*sizeof(AABB));
+
+ stack[0]=0;
+ stack_ptr[0]=first;
+ aabb_stack[0]=aabb;
+ Vector3 center = sample_aabb.pos + sample_aabb.size * 0.5;
+
+
+ int stack_pos=0;
+ Color max_col;
+
+ //int reso = sampler_opts->params[VS::BAKED_LIGHT_SAMPLER_DETAIL_RATIO];
+
+ int lalimit = sample_aabb.get_longest_axis_index();
+ float limit = sampler_opts->params[VS::BAKED_LIGHT_SAMPLER_DETAIL_RATIO]*sample_aabb.size[lalimit];
+
+
+ while(true) {
+
+
+ bool leaf = (rptr[ stack_ptr[stack_pos] ]>>16)==0;
+
+ if (aabb_stack[stack_pos].size[lalimit]<limit) {
+ leaf=true;
+ }
+
+
+ if (leaf) {
+
+ Vector3 from = aabb_stack[stack_pos].pos + aabb_stack[stack_pos].size * 0.5;
+ Vector3 norm = (from-center).normalized();
+
+
+ Color col;
+ col.r = ((rptr[ stack_ptr[stack_pos] ]&0xFFFF)/256.0);
+ col.g = ((rptr[ stack_ptr[stack_pos]+1 ]>>16)/256.0);
+ col.b = ((rptr[ stack_ptr[stack_pos]+1 ]&0xFFFF)/256.0);
+
+
+ max_col.r = MAX(max_col.r,col.r);
+ max_col.g = MAX(max_col.g,col.g);
+ max_col.b = MAX(max_col.b,col.b);
+
+ if (!islinear && p_linear_colorspace) {
+ col=col.to_linear();
+ }
+
+ float distance;
+
+ if (aabb_stack[stack_pos].has_point(center)) {
+ distance=0;
+ } else {
+
+ Vector3 support = aabb_stack[stack_pos].get_support(norm);
+ distance = Math::absf(norm.dot(support)-norm.dot(center));
+
+ }
+
+ if (distance>r)
+ distance=r;
+
+ float mult = powf(1.0-distance/r,att)*str;
+ if (mult>0) {
+ col.r*=mult;
+ col.g*=mult;
+ col.b*=mult;
+
+
+
+ for(int i=0;i<dp_size;i++) {
+ float mult2 = norm.dot(dp_normals[i]);
+ if (mult2<0)
+ mult2=0;
+ Color col2(col.r*mult2,col.g*mult2,col.b*mult2,1.0);
+ dp_map[i].r=MAX(dp_map[i].r,col2.r);
+ dp_map[i].g=MAX(dp_map[i].g,col2.g);
+ dp_map[i].b=MAX(dp_map[i].b,col2.b);
+ }
+
+ }
+
+ samples++;
+ //nothing is valid unless you hit a leaf
+ valid=true;
+ stack_pos--;
+ } else if ((stack[stack_pos]&0xFF)<8) {
+
+ int i = stack[stack_pos]&0xFF;
+ int base = (stack[stack_pos]>>8);
+
+ if (!((rptr[ stack_ptr[stack_pos] ]>>16)&(1<<i))) {
+ //no bit, no test
+ stack[stack_pos]=(base<<8)+(i+1);
+ continue;
+ }
+
+ stack[stack_pos]=((base+1)<<8)+(i+1);
+
+ AABB child_aabb = aabb_stack[stack_pos];
+ child_aabb.size*=0.5;
+ if (i&1)
+ child_aabb.pos.x+=child_aabb.size.x;
+ if (i&2)
+ child_aabb.pos.y+=child_aabb.size.y;
+ if (i&4)
+ child_aabb.pos.z+=child_aabb.size.z;
+
+ if (!child_aabb.intersects(sample_aabb)) {
+ continue;
+ }
+
+ if (child_aabb.encloses(sample_aabb)) {
+ stack[stack_pos]=(base<<8)|8; //don't test the rest
+ }
+
+ stack_pos++;
+ ERR_FAIL_COND(stack_pos>=depth);
+
+ stack[stack_pos]=0;
+ stack_ptr[stack_pos]=rptr[ stack_ptr[stack_pos-1]+2+base ];
+ aabb_stack[stack_pos]=child_aabb;
+ } else {
+ stack_pos--;
+ if (stack_pos<0)
+ break;
+ }
+ }
+
+
+ }
+
+ //print_line("samples "+itos(samples) );
+
+ if (valid) {
+
+ for(int i=0;i<res;i++) {
+ //average seams to avoid aliasing
+ {
+ //top
+ int ofs1 = i;
+ int ofs2 = dp_size-res+i;
+ Color avg(
+ (dp_map[ofs1].r+dp_map[ofs2].r)*0.5,
+ (dp_map[ofs1].g+dp_map[ofs2].g)*0.5,
+ (dp_map[ofs1].b+dp_map[ofs2].b)*0.5,
+ 1.0
+ );
+ dp_map[ofs1]=avg;
+ dp_map[ofs2]=avg;
+ }
+ {
+ //bottom
+ int ofs1 = res*res-res+i;
+ int ofs2 = res*res+i;
+ Color avg(
+ (dp_map[ofs1].r+dp_map[ofs2].r)*0.5,
+ (dp_map[ofs1].g+dp_map[ofs2].g)*0.5,
+ (dp_map[ofs1].b+dp_map[ofs2].b)*0.5,
+ 1.0
+ );
+ dp_map[ofs1]=avg;
+ dp_map[ofs2]=avg;
+ }
+ {
+ //left
+ int ofs1 = i*res;
+ int ofs2 = res*res+(res-i-1)*res;
+ Color avg(
+ (dp_map[ofs1].r+dp_map[ofs2].r)*0.5,
+ (dp_map[ofs1].g+dp_map[ofs2].g)*0.5,
+ (dp_map[ofs1].b+dp_map[ofs2].b)*0.5,
+ 1.0
+ );
+ dp_map[ofs1]=avg;
+ dp_map[ofs2]=avg;
+ }
+ {
+ //right
+ int ofs1 = i*res+(res-1);
+ int ofs2 = res*res+(res-i-1)*res+(res-1);
+ Color avg(
+ (dp_map[ofs1].r+dp_map[ofs2].r)*0.5,
+ (dp_map[ofs1].g+dp_map[ofs2].g)*0.5,
+ (dp_map[ofs1].b+dp_map[ofs2].b)*0.5,
+ 1.0
+ );
+ dp_map[ofs1]=avg;
+ dp_map[ofs2]=avg;
+ }
+
+ }
+
+ rasterizer->sampled_light_dp_update(p_sampled_light->baked_light_sampler_info->sampled_light,dp_map,1.0);
+ for(Set<Instance*>::Element *F=p_sampled_light->baked_light_sampler_info->owned_instances.front();F;F=F->next()) {
+
+ F->get()->data.sampled_light=p_sampled_light->baked_light_sampler_info->sampled_light;
+ }
+
+
+ } else {
+
+ for(Set<Instance*>::Element *F=p_sampled_light->baked_light_sampler_info->owned_instances.front();F;F=F->next()) {
+
+ F->get()->data.sampled_light=RID(); //do not use because nothing close
+ }
+ }
+
+
+
+
+/*
+ highp vec3 vtx = vertex_interp;
+ vtx.z*=dual_paraboloid.y; //side to affect
+ vtx.z+=0.01;
+ dp_clip=vtx.z;
+ highp float len=length( vtx );
+ vtx=normalize(vtx);
+ vtx.xy/=1.0+vtx.z;
+ vtx.z = len*dual_paraboloid.x; // it's a reciprocal(len - z_near) / (z_far - z_near);
+ vtx+=normalize(vtx)*0.025;
+ vtx.z = vtx.z * 2.0 - 1.0; // fit to clipspace
+ vertex_interp=vtx;
+*/
+
+
+
+
+}
+
+
void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario) {
@@ -5248,6 +5841,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
/* STEP 2 - CULL */
int cull_count = p_scenario->octree.cull_convex(planes,instance_cull_result,MAX_INSTANCE_CULL);
light_cull_count=0;
+ light_samplers_culled=0;
/* print_line("OT: "+rtos( (OS::get_singleton()->get_ticks_usec()-t)/1000.0));
print_line("OTO: "+itos(p_scenario->octree.get_octant_count()));
@@ -5408,6 +6002,8 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
keep=true;
}
+
+
}
@@ -5420,6 +6016,13 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
cull_range.min=min;
if (max>cull_range.max)
cull_range.max=max;
+
+ if (ins->sampled_light && ins->sampled_light->baked_light_sampler_info->last_pass!=render_pass) {
+ if (light_samplers_culled<MAX_LIGHT_SAMPLERS) {
+ light_sampler_cull_result[light_samplers_culled++]=ins->sampled_light;
+ ins->sampled_light->baked_light_sampler_info->last_pass=render_pass;
+ }
+ }
}
}
@@ -5499,7 +6102,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
}
- {
+ { //this should eventually change to
//assign shadows by distance to camera
SortArray<Instance*,_InstanceLightsort> sorter;
sorter.sort(light_cull_result,light_cull_count);
@@ -5520,10 +6123,8 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
}
}
+ /* ENVIRONMENT */
-
- /* STEP 6 - PROCESS GEOMETRY AND DRAW SCENE*/
-
RID environment;
if (p_camera->env.is_valid()) //camera has more environment priority
environment=p_camera->env;
@@ -5532,6 +6133,22 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
else
environment=p_scenario->fallback_environment;
+
+ /* STEP 6 - SAMPLE BAKED LIGHT */
+
+ bool islinear =false;
+ if (environment.is_valid()) {
+ islinear = rasterizer->environment_is_fx_enabled(environment,VS::ENV_FX_SRGB);
+ }
+
+ for(int i=0;i<light_samplers_culled;i++) {
+
+ _process_sampled_light(p_camera->transform,light_sampler_cull_result[i],islinear);
+ }
+
+ /* STEP 7 - PROCESS GEOMETRY AND DRAW SCENE*/
+
+
rasterizer->begin_scene(p_viewport->viewport_data,environment,p_scenario->debug);
rasterizer->set_viewport(viewport_rect);
@@ -5838,6 +6455,7 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
desired_rect.x+=p_ofs_x;
desired_rect.y+=p_ofs_y;
+
// if the viewport is different than the actual one, change it
if ( p_viewport->render_target.is_valid() || viewport_rect.x != desired_rect.x ||
@@ -5847,7 +6465,7 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
viewport_rect=desired_rect;
- rasterizer->set_viewport(viewport_rect);
+ rasterizer->set_viewport(viewport_rect);
}
@@ -5995,7 +6613,14 @@ void VisualServerRaster::_draw_viewports() {
int window_w = OS::get_singleton()->get_video_mode(E->get()).width;
int window_h = OS::get_singleton()->get_video_mode(E->get()).height;
- _draw_viewport(vp,0,0,window_w,window_h);
+ Rect2 r(0,0,vp->rect.width,vp->rect.height);
+ if (r.size.width==0)
+ r.size.width=window_w;
+ if (r.size.height==0)
+ r.size.height=window_w;
+
+
+ _draw_viewport(vp,r.pos.x,r.pos.y,r.size.width,r.size.height);
}
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 8ed348affa..3064f9ceb0 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -51,6 +51,7 @@ class VisualServerRaster : public VisualServer {
MAX_LIGHTS_CULLED=256,
MAX_ROOM_CULL=32,
MAX_EXTERIOR_PORTALS=128,
+ MAX_LIGHT_SAMPLERS=256,
INSTANCE_ROOMLESS_MASK=(1<<20)
@@ -90,12 +91,29 @@ class VisualServerRaster : public VisualServer {
struct BakedLight {
Rasterizer::BakedLightData data;
+ DVector<int> sampler;
AABB octree_aabb;
Size2i octree_tex_size;
+ Size2i light_tex_size;
};
+ struct BakedLightSampler {
+ float params[BAKED_LIGHT_SAMPLER_MAX];
+ int resolution;
+ Vector<Vector3> dp_cache;
+
+ BakedLightSampler() {
+ params[BAKED_LIGHT_SAMPLER_STRENGTH]=1.0;
+ params[BAKED_LIGHT_SAMPLER_ATTENUATION]=1.0;
+ params[BAKED_LIGHT_SAMPLER_RADIUS]=1.0;
+ params[BAKED_LIGHT_SAMPLER_DETAIL_RATIO]=0.1;
+ resolution=16;
+ }
+ };
+
+ void _update_baked_light_sampler_dp_cache(BakedLightSampler * blsamp);
struct Camera {
enum Type {
@@ -169,6 +187,7 @@ class VisualServerRaster : public VisualServer {
List<Instance*>::Element *RE;
Instance *baked_light;
List<Instance*>::Element *BLE;
+ Instance *sampled_light;
bool exterior;
uint64_t last_render_pass;
@@ -179,6 +198,8 @@ class VisualServerRaster : public VisualServer {
InstanceSet lights;
bool light_cache_dirty;
+
+
struct RoomInfo {
Transform affine_inverse;
@@ -235,6 +256,23 @@ class VisualServerRaster : public VisualServer {
Transform affine_inverse;
List<Instance*> owned_instances;
};
+
+ struct BakedLightSamplerInfo {
+
+ Set<Instance*> baked_lights;
+ Set<Instance*> owned_instances;
+ BakedLightSampler *sampler;
+ int resolution;
+ Vector<Color> light_bufer;
+ RID sampled_light;
+ uint64_t last_pass;
+ Transform xform; // viewspace normal to lightspace, might not use one.
+ BakedLightSamplerInfo() {
+ sampler=NULL;
+ last_pass=0;
+ resolution=0;
+ }
+ };
struct ParticlesInfo {
@@ -247,6 +285,7 @@ class VisualServerRaster : public VisualServer {
ParticlesInfo *particles_info;
PortalInfo * portal_info;
BakedLightInfo * baked_light_info;
+ BakedLightSamplerInfo * baked_light_sampler_info;
Instance() {
@@ -282,6 +321,8 @@ class VisualServerRaster : public VisualServer {
baked_light=NULL;
baked_light_info=NULL;
+ baked_light_sampler_info=NULL;
+ sampled_light=NULL;
BLE=NULL;
light_cache_dirty=true;
@@ -603,6 +644,9 @@ class VisualServerRaster : public VisualServer {
int exterior_portal_cull_count;
bool exterior_visited;
+ Instance *light_sampler_cull_result[MAX_LIGHT_SAMPLERS];
+ int light_samplers_culled;
+
Instance *room_cull_result[MAX_ROOM_CULL];
int room_cull_count;
bool room_cull_enabled;
@@ -638,6 +682,7 @@ class VisualServerRaster : public VisualServer {
mutable RID_Owner<Portal> portal_owner;
mutable RID_Owner<BakedLight> baked_light_owner;
+ mutable RID_Owner<BakedLightSampler> baked_light_sampler_owner;
mutable RID_Owner<Camera> camera_owner;
mutable RID_Owner<Viewport> viewport_owner;
@@ -658,6 +703,8 @@ class VisualServerRaster : public VisualServer {
bool _test_portal_cull(Camera *p_camera, Instance *p_portal_from, Instance *p_portal_to);
void _cull_portal(Camera *p_camera, Instance *p_portal,Instance *p_from_portal);
void _cull_room(Camera *p_camera, Instance *p_room,Instance *p_from_portal=NULL);
+ void _process_sampled_light(const Transform &p_camera, Instance *p_sampled_light, bool p_linear_colorspace);
+
void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario);
void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect,float p_opacity);
void _render_canvas(Canvas *p_canvas,const Matrix32 &p_transform);
@@ -953,12 +1000,28 @@ public:
virtual void baked_light_set_octree(RID p_baked_light,const DVector<uint8_t> p_octree);
virtual DVector<uint8_t> baked_light_get_octree(RID p_baked_light) const;
+ virtual void baked_light_set_light(RID p_baked_light,const DVector<uint8_t> p_light);
+ virtual DVector<uint8_t> baked_light_get_light(RID p_baked_light) const;
+
+ virtual void baked_light_set_sampler_octree(RID p_baked_light,const DVector<int> &p_sampler);
+ virtual DVector<int> baked_light_get_sampler_octree(RID p_baked_light) const;
+
virtual void baked_light_set_lightmap_multiplier(RID p_baked_light,float p_multiplier);
virtual float baked_light_get_lightmap_multiplier(RID p_baked_light) const;
virtual void baked_light_add_lightmap(RID p_baked_light,const RID p_texture,int p_id);
virtual void baked_light_clear_lightmaps(RID p_baked_light);
+ /* BAKED LIGHT SAMPLER */
+
+ virtual RID baked_light_sampler_create();
+
+ virtual void baked_light_sampler_set_param(RID p_baked_light_sampler,BakedLightSamplerParam p_param,float p_value);
+ virtual float baked_light_sampler_get_param(RID p_baked_light_sampler,BakedLightSamplerParam p_param) const;
+
+ virtual void baked_light_sampler_set_resolution(RID p_baked_light_sampler,int p_resolution);
+ virtual int baked_light_sampler_get_resolution(RID p_baked_light_sampler) const;
+
/* CAMERA API */
virtual RID camera_create();
@@ -1096,6 +1159,9 @@ public:
virtual void instance_geometry_set_baked_light(RID p_instance,RID p_baked_light);
virtual RID instance_geometry_get_baked_light(RID p_instance) const;
+ virtual void instance_geometry_set_baked_light_sampler(RID p_instance,RID p_baked_light_sampler);
+ virtual RID instance_geometry_get_baked_light_sampler(RID p_instance) const;
+
virtual void instance_geometry_set_baked_light_texture_index(RID p_instance,int p_tex_id);
virtual int instance_geometry_get_baked_light_texture_index(RID p_instance) const;
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 1ad8c85986..a4653b1013 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -909,6 +909,12 @@ public:
FUNC2(baked_light_set_octree,RID,DVector<uint8_t>);
FUNC1RC(DVector<uint8_t>,baked_light_get_octree,RID);
+ FUNC2(baked_light_set_light,RID,DVector<uint8_t>);
+ FUNC1RC(DVector<uint8_t>,baked_light_get_light,RID);
+
+ FUNC2(baked_light_set_sampler_octree,RID,const DVector<int>&);
+ FUNC1RC(DVector<int>,baked_light_get_sampler_octree,RID);
+
FUNC2(baked_light_set_lightmap_multiplier,RID,float);
FUNC1RC(float,baked_light_get_lightmap_multiplier,RID);
@@ -916,6 +922,14 @@ public:
FUNC1(baked_light_clear_lightmaps,RID);
+ FUNC0R(RID,baked_light_sampler_create);
+
+ FUNC3(baked_light_sampler_set_param,RID, BakedLightSamplerParam , float );
+ FUNC2RC(float,baked_light_sampler_get_param,RID, BakedLightSamplerParam );
+
+ FUNC2(baked_light_sampler_set_resolution,RID,int);
+ FUNC1RC(int,baked_light_sampler_get_resolution,RID);
+
/* CAMERA API */
FUNC0R(RID,camera_create);
@@ -1055,6 +1069,9 @@ public:
FUNC2(instance_geometry_set_baked_light,RID, RID );
FUNC1RC(RID,instance_geometry_get_baked_light,RID);
+ FUNC2(instance_geometry_set_baked_light_sampler,RID, RID );
+ FUNC1RC(RID,instance_geometry_get_baked_light_sampler,RID);
+
FUNC2(instance_geometry_set_baked_light_texture_index,RID, int);
FUNC1RC(int,instance_geometry_get_baked_light_texture_index,RID);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 366758f1d8..ed04b0d09c 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -590,12 +590,35 @@ public:
virtual void baked_light_set_octree(RID p_baked_light,const DVector<uint8_t> p_octree)=0;
virtual DVector<uint8_t> baked_light_get_octree(RID p_baked_light) const=0;
+ virtual void baked_light_set_light(RID p_baked_light,const DVector<uint8_t> p_light)=0;
+ virtual DVector<uint8_t> baked_light_get_light(RID p_baked_light) const=0;
+
+ virtual void baked_light_set_sampler_octree(RID p_baked_light,const DVector<int> &p_sampler)=0;
+ virtual DVector<int> baked_light_get_sampler_octree(RID p_baked_light) const=0;
+
virtual void baked_light_set_lightmap_multiplier(RID p_baked_light,float p_multiplier)=0;
virtual float baked_light_get_lightmap_multiplier(RID p_baked_light) const=0;
virtual void baked_light_add_lightmap(RID p_baked_light,const RID p_texture,int p_id)=0;
virtual void baked_light_clear_lightmaps(RID p_baked_light)=0;
+ /* BAKED LIGHT SAMPLER */
+
+ virtual RID baked_light_sampler_create()=0;
+
+ enum BakedLightSamplerParam {
+ BAKED_LIGHT_SAMPLER_RADIUS,
+ BAKED_LIGHT_SAMPLER_STRENGTH,
+ BAKED_LIGHT_SAMPLER_ATTENUATION,
+ BAKED_LIGHT_SAMPLER_DETAIL_RATIO,
+ BAKED_LIGHT_SAMPLER_MAX
+ };
+
+ virtual void baked_light_sampler_set_param(RID p_baked_light_sampler,BakedLightSamplerParam p_param,float p_value)=0;
+ virtual float baked_light_sampler_get_param(RID p_baked_light_sampler,BakedLightSamplerParam p_param) const=0;
+
+ virtual void baked_light_sampler_set_resolution(RID p_baked_light_sampler,int p_resolution)=0;
+ virtual int baked_light_sampler_get_resolution(RID p_baked_light_sampler) const=0;
/* CAMERA API */
@@ -824,7 +847,8 @@ public:
INSTANCE_ROOM,
INSTANCE_PORTAL,
INSTANCE_BAKED_LIGHT,
-
+ INSTANCE_BAKED_LIGHT_SAMPLER,
+
INSTANCE_GEOMETRY_MASK=(1<<INSTANCE_MESH)|(1<<INSTANCE_MULTIMESH)|(1<<INSTANCE_IMMEDIATE)|(1<<INSTANCE_PARTICLES)
};
@@ -898,9 +922,13 @@ public:
virtual void instance_geometry_set_baked_light(RID p_instance,RID p_baked_light)=0;
virtual RID instance_geometry_get_baked_light(RID p_instance) const=0;
+ virtual void instance_geometry_set_baked_light_sampler(RID p_instance,RID p_baked_light_sampler)=0;
+ virtual RID instance_geometry_get_baked_light_sampler(RID p_instance) const=0;
+
virtual void instance_geometry_set_baked_light_texture_index(RID p_instance,int p_tex_id)=0;
virtual int instance_geometry_get_baked_light_texture_index(RID p_instance) const=0;
+
virtual void instance_light_set_enabled(RID p_instance,bool p_enabled)=0;
virtual bool instance_light_is_enabled(RID p_instance) const=0;
diff --git a/tools/collada/collada.cpp b/tools/collada/collada.cpp
index 7f4f92e82d..7a842391a4 100644
--- a/tools/collada/collada.cpp
+++ b/tools/collada/collada.cpp
@@ -2106,6 +2106,8 @@ void Collada::_parse_animation_clip(XMLParser& parser) {
if (parser.has_attribute("name"))
clip.name=parser.get_attribute_value("name");
+ else if (parser.has_attribute("id"))
+ clip.name=parser.get_attribute_value("id");
if (parser.has_attribute("start"))
clip.begin=parser.get_attribute_value("start").to_double();
if (parser.has_attribute("end"))
diff --git a/tools/docdump/makemd.py b/tools/docdump/makemd.py
index 7cc2e9dc4b..f85d145d5e 100644
--- a/tools/docdump/makemd.py
+++ b/tools/docdump/makemd.py
@@ -337,7 +337,7 @@ for file in input_list:
class_names.sort()
-make_class_list(class_names, 3)
+make_class_list(class_names, 2)
for cn in class_names:
c = classes[cn]
diff --git a/tools/editor/plugins/baked_light_baker.cpp b/tools/editor/plugins/baked_light_baker.cpp
index 3774b7d25b..42a185b7c2 100644
--- a/tools/editor/plugins/baked_light_baker.cpp
+++ b/tools/editor/plugins/baked_light_baker.cpp
@@ -4,8 +4,17 @@
#include <cmath>
#include "io/marshalls.h"
#include "tools/editor/editor_node.h"
+#include "tools/editor/editor_settings.h"
+void baked_light_baker_add_64f(double *dst,double value);
+void baked_light_baker_add_64i(int64_t *dst,int64_t value);
+
+//-separar en 2 testuras?
+//*mejorar performance y threads
+//*modos lineales
+//*saturacion
+
_FORCE_INLINE_ static uint64_t get_uv_normal_bit(const Vector3& p_vector) {
int lat = Math::fast_ftoi(Math::floor(Math::acos(p_vector.dot(Vector3(0,1,0)))*6.0/Math_PI+0.5));
@@ -66,6 +75,12 @@ BakedLightBaker::MeshTexture* BakedLightBaker::_get_mat_tex(const Ref<Texture>&
image.convert(Image::FORMAT_RGBA);
}
+ if (imgtex->get_flags()&Texture::FLAG_CONVERT_TO_LINEAR) {
+ Image copy = image;
+ copy.srgb_to_linear();
+ image=copy;
+ }
+
DVector<uint8_t> dvt=image.get_data();
DVector<uint8_t>::Read r=dvt.read();
MeshTexture mt;
@@ -105,8 +120,13 @@ void BakedLightBaker::_add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_m
if (fm.is_valid()) {
//fixed route
mm.diffuse.color=fm->get_parameter(FixedMaterial::PARAM_DIFFUSE);
+ if (linear_color)
+ mm.diffuse.color=mm.diffuse.color.to_linear();
mm.diffuse.tex=_get_mat_tex(fm->get_texture(FixedMaterial::PARAM_DIFFUSE));
mm.specular.color=fm->get_parameter(FixedMaterial::PARAM_SPECULAR);
+ if (linear_color)
+ mm.specular.color=mm.specular.color.to_linear();
+
mm.specular.tex=_get_mat_tex(fm->get_texture(FixedMaterial::PARAM_SPECULAR));
} else {
@@ -270,6 +290,11 @@ void BakedLightBaker::_parse_geometry(Node* p_node) {
dirl.type=VS::LightType(dl->get_light_type());
dirl.diffuse=dl->get_color(DirectionalLight::COLOR_DIFFUSE);
dirl.specular=dl->get_color(DirectionalLight::COLOR_SPECULAR);
+ if (linear_color)
+ dirl.diffuse=dirl.diffuse.to_linear();
+ if (linear_color)
+ dirl.specular=dirl.specular.to_linear();
+
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();
@@ -472,8 +497,11 @@ void BakedLightBaker::_make_bvh() {
}
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);
+
+ bvh_depth = max_depth;
}
void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_depth) {
@@ -563,6 +591,12 @@ void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_de
child->aabb.pos.z+=child->aabb.size.z;
+ child->full_accum[0]=0;
+ child->full_accum[1]=0;
+ child->full_accum[2]=0;
+ child->sampler_ofs=0;
+
+
if (stack_pos==octree_depth-1) {
child->leaf=true;
@@ -585,14 +619,10 @@ void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_de
cell_count++;
int lz = lights.size();
- child->light = memnew_arr(OctantLight,lz);
-
- for(int li=0;li<lz;li++) {
- for(int ci=0;ci<8;ci++) {
- child->light[li].accum[ci][0]=0;
- child->light[li].accum[ci][1]=0;
- child->light[li].accum[ci][2]=0;
- }
+ for(int ci=0;ci<8;ci++) {
+ child->light_accum[ci][0]=0;
+ child->light_accum[ci][1]=0;
+ child->light_accum[ci][2]=0;
}
child->parent=ptr_stack[stack_pos];
@@ -797,12 +827,12 @@ void BakedLightBaker::_make_octree() {
-void BakedLightBaker::_plot_light(int p_light_index, const Vector3& p_plot_pos, const AABB& p_plot_aabb, const Color& p_light, const Plane& p_plane) {
+void BakedLightBaker::_plot_light(ThreadStack& thread_stack,const Vector3& p_plot_pos, const AABB& p_plot_aabb, const Color& p_light,const Color& p_tint_light,bool p_only_full, const Plane& p_plane) {
//stackless version
- uint32_t *stack=octant_stack;
- uint32_t *ptr_stack=octantptr_stack;
+ uint32_t *stack=thread_stack.octant_stack;
+ uint32_t *ptr_stack=thread_stack.octantptr_stack;
Octant *octants=octant_pool.ptr();
stack[0]=0;
@@ -815,6 +845,29 @@ void BakedLightBaker::_plot_light(int p_light_index, const Vector3& p_plot_pos,
Octant &octant=octants[ptr_stack[stack_pos]];
+ if (stack[stack_pos]==0) {
+
+
+ Vector3 pos = octant.aabb.pos + octant.aabb.size*0.5;
+ float md = 1<<(octree_depth - stack_pos );
+ float r=cell_size*plot_size*md;
+ float div = 1.0/(md*md*md);
+ //div=1.0;
+
+
+ float d = p_plot_pos.distance_to(pos);
+
+ if ((p_plane.distance_to(pos)>-cell_size*1.75*md) && d<=r) {
+
+
+ float intensity = 1.0 - (d/r)*(d/r); //not gauss but..
+
+ baked_light_baker_add_64f(&octant.full_accum[0],p_tint_light.r*intensity*div);
+ baked_light_baker_add_64f(&octant.full_accum[1],p_tint_light.g*intensity*div);
+ baked_light_baker_add_64f(&octant.full_accum[2],p_tint_light.b*intensity*div);
+ }
+ }
+
if (octant.leaf) {
@@ -822,41 +875,44 @@ void BakedLightBaker::_plot_light(int p_light_index, const Vector3& p_plot_pos,
//if (p_plane.normal.dot(octant.aabb.get_support(p_plane.normal)) < p_plane.d-CMP_EPSILON) { //octants behind are no go
-
- float r=cell_size*plot_size;
- for(int i=0;i<8;i++) {
- Vector3 pos=octant.aabb.pos;
- if (i&1)
- pos.x+=octant.aabb.size.x;
- if (i&2)
- pos.y+=octant.aabb.size.y;
- if (i&4)
- pos.z+=octant.aabb.size.z;
+ if (!p_only_full) {
+ float r=cell_size*plot_size;
+ for(int i=0;i<8;i++) {
+ Vector3 pos=octant.aabb.pos;
+ if (i&1)
+ pos.x+=octant.aabb.size.x;
+ if (i&2)
+ pos.y+=octant.aabb.size.y;
+ if (i&4)
+ pos.z+=octant.aabb.size.z;
- float d = p_plot_pos.distance_to(pos);
+ float d = p_plot_pos.distance_to(pos);
- if ((p_plane.distance_to(pos)>-cell_size*1.75) && d<=r) {
+ if ((p_plane.distance_to(pos)>-cell_size*1.75) && d<=r) {
- float intensity = 1.0 - (d/r)*(d/r); //not gauss but..
- if (edge_damp>0) {
- Vector3 normal = Vector3(octant.normal_accum[i][0],octant.normal_accum[i][1],octant.normal_accum[i][2]);
- if (normal.x>0 || normal.y>0 || normal.z>0) {
+ float intensity = 1.0 - (d/r)*(d/r); //not gauss but..
+ if (edge_damp>0) {
+ Vector3 normal = Vector3(octant.normal_accum[i][0],octant.normal_accum[i][1],octant.normal_accum[i][2]);
+ if (normal.x>0 || normal.y>0 || normal.z>0) {
- float damp = Math::abs(p_plane.normal.dot(normal));
- intensity*=pow(damp,edge_damp);
+ float damp = Math::abs(p_plane.normal.dot(normal));
+ intensity*=pow(damp,edge_damp);
+ }
}
- }
- //intensity*=1.0-Math::abs(p_plane.distance_to(pos))/(plot_size*cell_size);
- //intensity = Math::cos(d*Math_PI*0.5/r);
+ //intensity*=1.0-Math::abs(p_plane.distance_to(pos))/(plot_size*cell_size);
+ //intensity = Math::cos(d*Math_PI*0.5/r);
+
+ baked_light_baker_add_64f(&octant.light_accum[i][0],p_light.r*intensity);
+ baked_light_baker_add_64f(&octant.light_accum[i][1],p_light.g*intensity);
+ baked_light_baker_add_64f(&octant.light_accum[i][2],p_light.b*intensity);
+
- octant.light[p_light_index].accum[i][0]+=p_light.r*intensity;
- octant.light[p_light_index].accum[i][1]+=p_light.g*intensity;
- octant.light[p_light_index].accum[i][2]+=p_light.b*intensity;
+ }
}
}
@@ -893,11 +949,11 @@ void BakedLightBaker::_plot_light(int p_light_index, const Vector3& p_plot_pos,
}
-float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce,bool p_only_dist) {
+float BakedLightBaker::_throw_ray(ThreadStack& thread_stack,bool p_bake_direct,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce,bool p_only_dist) {
- uint32_t* stack = ray_stack;
- BVH **bstack = bvh_stack;
+ uint32_t* stack = thread_stack.ray_stack;
+ BVH **bstack = thread_stack.bvh_stack;
enum {
TEST_AABB_BIT=0,
@@ -915,6 +971,7 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons
n/=len;
+
real_t d=1e10;
bool inters=false;
Vector3 r_normal;
@@ -1139,7 +1196,7 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons
#endif
- ret=_throw_ray(p_light_index,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1);
+ ret=_throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1);
}
if (use_specular && (specular_at_point.r>CMP_EPSILON || specular_at_point.g>CMP_EPSILON || specular_at_point.b>CMP_EPSILON)) {
@@ -1150,7 +1207,7 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons
Vector3 rn = n - r_normal *r_normal.dot(n) * 2.0;
- _throw_ray(p_light_index,r_point,r_point+rn*p_rest,p_rest,specular_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1);
+ _throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,specular_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1);
}
}
@@ -1158,19 +1215,25 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons
// _plot_light_point(r_point,octree,octree_aabb,p_light);
- Color plot_light=diffuse_at_point;
+ Color plot_light=res_light.linear_interpolate(diffuse_at_point,tint);
plot_light.r*=att;
plot_light.g*=att;
plot_light.b*=att;
+ Color tint_light=diffuse_at_point;
+ tint_light.r*=att;
+ tint_light.g*=att;
+ tint_light.b*=att;
+
+ bool skip=false;
- if (!p_first_bounce) {
+ if (!p_first_bounce || p_bake_direct) {
float r = plot_size * cell_size*2;
if (dist<r) {
//avoid accumulaiton of light on corners
//plot_light=plot_light.linear_interpolate(Color(0,0,0,0),1.0-sd/plot_size*plot_size);
- plot_light=Color(0,0,0,0);
+ skip-true;
} else {
@@ -1181,12 +1244,12 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons
double r2 = double(rand())/RAND_MAX;
double r3 = double(rand())/RAND_MAX;
Vector3 rn = ((c1*(r1-0.5)) + (c2*(r2-0.5)) + (r_normal*r3*0.25)).normalized();
- float d =_throw_ray(p_light_index,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1,false,true);
- r = plot_size*cell_size*0.7;
+ float d =_throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1,false,true);
+ r = plot_size*cell_size*ao_radius;
if (d>0 && d<r) {
//avoid accumulaiton of light on corners
//plot_light=plot_light.linear_interpolate(Color(0,0,0,0),1.0-sd/plot_size*plot_size);
- plot_light=Color(0,0,0,0);
+ skip=true;
} else {
//plot_light=Color(0,0,0,0);
@@ -1195,11 +1258,9 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons
}
- if (!p_first_bounce || lights[p_light_index].bake_direct) {
- Plane plane(r_point,r_normal);
- //print_line(String(plot_light)+String(" ")+rtos(att));
- _plot_light(p_light_index,r_point,aabb,plot_light,plane);
- }
+ Plane plane(r_point,r_normal);
+ if (!skip)
+ _plot_light(thread_stack,r_point,aabb,plot_light,tint_light,!(!p_first_bounce || p_bake_direct),plane);
return dist;
@@ -1305,79 +1366,100 @@ void BakedLightBaker::_make_octree_texture() {
//ok let's try to just create a texture
- {
+ int otex_w=256;
- int otex_w=(1<<lattice_size)*(1<<lattice_size)*2; //make sure lattice fits horizontally
- Vector3 lattice_cell_size=octree_aabb.size;
- for(int i=0;i<lattice_size;i++) {
+ while (true) {
- lattice_cell_size*=0.5;
- }
+ uint32_t oct_idx=leaf_list;
- while(true) {
+ int row=0;
- //let's plot the leafs first, given the octree is not so obvious which size it will have
- int row=4+4*(1<<lattice_size);
+ print_line("begin at row "+itos(row));
+ int longest_line_reused=0;
+ int col=0;
+ int processed=0;
+
+ //reset
+ while(oct_idx) {
- uint32_t oct_idx=leaf_list;
+ BakedLightBaker::Octant *oct = &octants[oct_idx];
+ oct->texture_x=0;
+ oct->texture_y=0;
+ oct_idx=oct->next_leaf;
- //untag
- while(oct_idx) {
+ }
- BakedLightBaker::Octant *oct = &octants[oct_idx];
- //0,0 also means unprocessed
- oct->texture_x=0;
- oct->texture_y=0;
- oct_idx=oct->next_leaf;
+ oct_idx=leaf_list;
+ //assign
+ while(oct_idx) {
+ BakedLightBaker::Octant *oct = &octants[oct_idx];
+ if (oct->first_neighbour && oct->texture_x==0 && oct->texture_y==0) {
+ //was not processed
+ uint32_t current_idx=oct_idx;
+ int reused=0;
+
+ while(current_idx) {
+ BakedLightBaker::Octant *o = &octants[current_idx];
+ if (col+1 >= otex_w) {
+ col=0;
+ row+=4;
+ }
+ o->texture_x=col;
+ o->texture_y=row;
+ processed++;
+
+ if (o->bake_neighbour) {
+ reused++;
+ }
+ col+=o->bake_neighbour ? 1 : 2; //reuse neighbour
+ current_idx=o->bake_neighbour;
+ }
+
+ if (reused>longest_line_reused) {
+ longest_line_reused=reused;
+ }
}
+ oct_idx=oct->next_leaf;
+ }
- oct_idx=leaf_list;
+ row+=4;
+ if (otex_w < row) {
- print_line("begin at row "+itos(row));
- int longest_line_reused=0;
- int col=0;
- int processed=0;
+ otex_w*=2;
+ } else {
+
+ baked_light_texture_w=otex_w;
+ baked_light_texture_h=nearest_power_of_2(row);
+ print_line("w: "+itos(otex_w));
+ print_line("h: "+itos(row));
+ break;
+ }
- while(oct_idx) {
- BakedLightBaker::Octant *oct = &octants[oct_idx];
- if (oct->first_neighbour && oct->texture_x==0 && oct->texture_y==0) {
- //was not processed
- uint32_t current_idx=oct_idx;
- int reused=0;
+ }
- while(current_idx) {
- BakedLightBaker::Octant *o = &octants[current_idx];
- if (col+1 >= otex_w) {
- col=0;
- row+=4;
- }
- o->texture_x=col;
- o->texture_y=row;
- processed++;
- if (o->bake_neighbour) {
- reused++;
- }
- col+=o->bake_neighbour ? 1 : 2; //reuse neighbour
- current_idx=o->bake_neighbour;
- }
+ {
- if (reused>longest_line_reused) {
- longest_line_reused=reused;
- }
- }
- oct_idx=oct->next_leaf;
- }
+ otex_w=(1<<lattice_size)*(1<<lattice_size)*2; //make sure lattice fits horizontally
+ Vector3 lattice_cell_size=octree_aabb.size;
+ for(int i=0;i<lattice_size;i++) {
+
+ lattice_cell_size*=0.5;
+ }
- print_line("processed "+itos(processed));
- print_line("longest reused: "+itos(longest_line_reused));
+
+ while(true) {
+
+ //let's plot the leafs first, given the octree is not so obvious which size it will have
+ int row=4+4*(1<<lattice_size);
+ int col=0;
col=0;
row+=4;
@@ -1478,7 +1560,25 @@ double BakedLightBaker::get_normalization(int p_light_idx) const {
return nrg;
}
-void BakedLightBaker::throw_rays(int p_amount) {
+
+
+double BakedLightBaker::get_modifier(int p_light_idx) const {
+
+ double nrg=0;
+
+ const LightData &dl=lights[p_light_idx];
+ double cell_area = cell_size*cell_size;;
+ //nrg+= /*dl.energy */ (dl.rays_thrown * cell_area / dl.area);
+ nrg=cell_area;
+ nrg*=(Math_PI*plot_size*plot_size)*0.5; // damping of radial linear gradient kernel
+ nrg*=dl.constant;
+ //nrg*=5;
+
+
+ return nrg;
+}
+
+void BakedLightBaker::throw_rays(ThreadStack& thread_stack,int p_amount) {
@@ -1488,6 +1588,8 @@ void BakedLightBaker::throw_rays(int p_amount) {
int amount = p_amount * total_light_area / dl.area;
+ double mod = 1.0/double(get_modifier(i));
+ mod*=p_amount/float(amount);
switch(dl.type) {
@@ -1502,12 +1604,15 @@ void BakedLightBaker::throw_rays(int p_amount) {
from+=dl.left*(r2*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;
+ float m = mod*dl.energy;
+ col.r*=m;
+ col.g*=m;
+ col.b*=m;
+
dl.rays_thrown++;
- total_rays++;
- _throw_ray(i,from,to,dl.length,col,NULL,0,0,max_bounces,true);
+ baked_light_baker_add_64i(&total_rays,1);
+
+ _throw_ray(thread_stack,dl.bake_direct,from,to,dl.length,col,NULL,0,0,max_bounces,true);
}
} break;
case VS::LIGHT_OMNI: {
@@ -1543,13 +1648,14 @@ void BakedLightBaker::throw_rays(int p_amount) {
#endif
Vector3 to = dl.pos+dir*dl.radius;
Color col=dl.diffuse;
- col.r*=dl.energy;
- col.g*=dl.energy;
- col.b*=dl.energy;
+ float m = mod*dl.energy;
+ col.r*=m;
+ col.g*=m;
+ col.b*=m;
dl.rays_thrown++;
- total_rays++;
- _throw_ray(i,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true);
+ baked_light_baker_add_64i(&total_rays,1);
+ _throw_ray(thread_stack,dl.bake_direct,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true);
// _throw_ray(i,from,to,dl.radius,col,NULL,0,dl.radius,max_bounces,true);
}
@@ -1574,13 +1680,14 @@ void BakedLightBaker::throw_rays(int p_amount) {
Vector3 to = dl.pos+dir*dl.radius;
Color col=dl.diffuse;
- col.r*=dl.energy;
- col.g*=dl.energy;
- col.b*=dl.energy;
+ float m = mod*dl.energy;
+ col.r*=m;
+ col.g*=m;
+ col.b*=m;
dl.rays_thrown++;
- total_rays++;
- _throw_ray(i,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true);
+ baked_light_baker_add_64i(&total_rays,1);
+ _throw_ray(thread_stack,dl.bake_direct,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true);
// _throw_ray(i,from,to,dl.radius,col,NULL,0,dl.radius,max_bounces,true);
}
@@ -1622,6 +1729,10 @@ void BakedLightBaker::bake(const Ref<BakedLight> &p_light, Node* p_node) {
edge_damp=baked_light->get_edge_damp();
normal_damp=baked_light->get_normal_damp();
octree_extra_margin=baked_light->get_cell_extra_margin();
+ tint=baked_light->get_tint();
+ ao_radius=baked_light->get_ao_radius();
+ ao_strength=baked_light->get_ao_strength();
+ linear_color=baked_light->get_bake_flag(BakedLight::BAKE_LINEAR_COLOR);
baked_textures.clear();
for(int i=0;i<baked_light->get_lightmaps_count();i++) {
@@ -1651,13 +1762,134 @@ void BakedLightBaker::bake(const Ref<BakedLight> &p_light, Node* p_node) {
}
-void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) {
+void BakedLightBaker::update_octree_sampler(DVector<int> &p_sampler) {
+
+ BakedLightBaker::Octant *octants=octant_pool.ptr();
+ double norm = 1.0/double(total_rays);
+
+
+
+ if (p_sampler.size()==0 || first_bake_to_map) {
+
+ Vector<int> tmp_smp;
+ tmp_smp.resize(32); //32 for header
+
+ for(int i=0;i<32;i++) {
+ tmp_smp[i]=0;
+ }
+
+ for(int i=octant_pool_size-1;i>=0;i--) {
+
+ if (i==0)
+ tmp_smp[1]=tmp_smp.size();
+
+ Octant &octant=octants[i];
+ octant.sampler_ofs = tmp_smp.size();
+ int idxcol[2]={0,0};
+
+ int r = CLAMP((octant.full_accum[0]*norm)*2048,0,32767);
+ int g = CLAMP((octant.full_accum[1]*norm)*2048,0,32767);
+ int b = CLAMP((octant.full_accum[2]*norm)*2048,0,32767);
+
+ idxcol[0]|=r;
+ idxcol[1]|=(g<<16)|b;
+
+ if (octant.leaf) {
+ tmp_smp.push_back(idxcol[0]);
+ tmp_smp.push_back(idxcol[1]);
+ } else {
+
+ for(int j=0;j<8;j++) {
+ if (octant.children[j]) {
+ idxcol[0]|=(1<<(j+16));
+ }
+ }
+ tmp_smp.push_back(idxcol[0]);
+ tmp_smp.push_back(idxcol[1]);
+ for(int j=0;j<8;j++) {
+ if (octant.children[j]) {
+ tmp_smp.push_back(octants[octant.children[j]].sampler_ofs);
+ if (octants[octant.children[j]].sampler_ofs==0) {
+ print_line("FUUUUUUUUCK");
+ }
+ }
+ }
+ }
+
+ }
+
+ p_sampler.resize(tmp_smp.size());
+ DVector<int>::Write w = p_sampler.write();
+ int ss = tmp_smp.size();
+ for(int i=0;i<ss;i++) {
+ w[i]=tmp_smp[i];
+ }
+
+ first_bake_to_map=false;
+
+ }
+
+ double gamma = baked_light->get_gamma_adjust();
+ double mult = baked_light->get_energy_multiplier();
+ float saturation = baked_light->get_saturation();
+
+ DVector<int>::Write w = p_sampler.write();
+
+ encode_uint32(octree_depth,(uint8_t*)&w[2]);
+ encode_uint32(linear_color,(uint8_t*)&w[3]);
+
+ encode_float(octree_aabb.pos.x,(uint8_t*)&w[4]);
+ encode_float(octree_aabb.pos.y,(uint8_t*)&w[5]);
+ encode_float(octree_aabb.pos.z,(uint8_t*)&w[6]);
+ encode_float(octree_aabb.size.x,(uint8_t*)&w[7]);
+ encode_float(octree_aabb.size.y,(uint8_t*)&w[8]);
+ encode_float(octree_aabb.size.z,(uint8_t*)&w[9]);
+
+ //norm*=multiplier;
+
+ for(int i=octant_pool_size-1;i>=0;i--) {
+
+ Octant &octant=octants[i];
+ int idxcol[2]={w[octant.sampler_ofs],w[octant.sampler_ofs+1]};
+
+ double rf=pow(octant.full_accum[0]*norm*mult,gamma);
+ double gf=pow(octant.full_accum[1]*norm*mult,gamma);
+ double bf=pow(octant.full_accum[2]*norm*mult,gamma);
+
+ double gray = (rf+gf+bf)/3.0;
+ rf = gray + (rf-gray)*saturation;
+ gf = gray + (gf-gray)*saturation;
+ bf = gray + (bf-gray)*saturation;
+
+
+ int r = CLAMP((rf)*2048,0,32767);
+ int g = CLAMP((gf)*2048,0,32767);
+ int b = CLAMP((bf)*2048,0,32767);
+
+ idxcol[0]=((idxcol[0]>>16)<<16)|r;
+ idxcol[1]=(g<<16)|b;
+ w[octant.sampler_ofs]=idxcol[0];
+ w[octant.sampler_ofs+1]=idxcol[1];
+ }
+
+}
+
+void BakedLightBaker::update_octree_images(DVector<uint8_t> &p_octree,DVector<uint8_t> &p_light) {
int len = baked_octree_texture_w*baked_octree_texture_h*4;
- p_image.resize(len);
- DVector<uint8_t>::Write w = p_image.write();
+ p_octree.resize(len);
+
+ int ilen = baked_light_texture_w*baked_light_texture_h*4;
+ p_light.resize(ilen);
+
+
+ DVector<uint8_t>::Write w = p_octree.write();
zeromem(w.ptr(),len);
+
+ DVector<uint8_t>::Write iw = p_light.write();
+ zeromem(iw.ptr(),ilen);
+
float gamma = baked_light->get_gamma_adjust();
float mult = baked_light->get_energy_multiplier();
@@ -1668,6 +1900,13 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) {
w[i+3]=0xFF;
}
+ for(int i=0;i<ilen;i+=4) {
+ iw[i+0]=0xFF;
+ iw[i+1]=0;
+ iw[i+2]=0xFF;
+ iw[i+3]=0xFF;
+ }
+
float multiplier=1.0;
if (baked_light->get_format()==BakedLight::FORMAT_HDR8)
@@ -1678,6 +1917,9 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) {
encode_float(1<<lattice_size,&w[12]);
encode_uint32(octree_depth-lattice_size,&w[16]);
encode_uint32(multiplier,&w[20]);
+ encode_uint16(baked_light_texture_w,&w[24]); //if present, use the baked light texture
+ encode_uint16(baked_light_texture_h,&w[26]);
+ encode_uint32(0,&w[28]); //baked light texture format
encode_float(octree_aabb.pos.x,&w[32]);
encode_float(octree_aabb.pos.y,&w[36]);
@@ -1690,6 +1932,7 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) {
BakedLightBaker::Octant *octants=octant_pool.ptr();
int octant_count=octant_pool_size;
uint8_t *ptr = w.ptr();
+ uint8_t *lptr = iw.ptr();
int child_offsets[8]={
@@ -1703,7 +1946,18 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) {
baked_octree_texture_w*8+baked_octree_texture_w*4+4,
};
- Vector<double> norm_arr;
+ int lchild_offsets[8]={
+ 0,
+ 4,
+ baked_light_texture_w*4,
+ baked_light_texture_w*4+4,
+ baked_light_texture_w*8+0,
+ baked_light_texture_w*8+4,
+ baked_light_texture_w*8+baked_light_texture_w*4,
+ baked_light_texture_w*8+baked_light_texture_w*4+4,
+ };
+
+ /*Vector<double> norm_arr;
norm_arr.resize(lights.size());
for(int i=0;i<lights.size();i++) {
@@ -1711,39 +1965,43 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) {
}
const double *normptr=norm_arr.ptr();
-
+*/
+ double norm = 1.0/double(total_rays);
int lz=lights.size();
mult/=multiplier;
+ double saturation = baked_light->get_saturation();
for(int i=0;i<octant_count;i++) {
Octant &oct=octants[i];
if (oct.texture_x==0 && oct.texture_y==0)
continue;
- int ofs = (oct.texture_y * baked_octree_texture_w + oct.texture_x)<<2;
+
if (oct.leaf) {
+ int ofs = (oct.texture_y * baked_light_texture_w + oct.texture_x)<<2;
+ ERR_CONTINUE(ofs<0 || ofs >ilen);
//write colors
for(int j=0;j<8;j++) {
//if (!oct.children[j])
// continue;
- uint8_t *iptr=&ptr[ofs+child_offsets[j]];
- float r=0;
- float g=0;
- float b=0;
-
- for(int k=0;k<lz;k++) {
- r+=oct.light[k].accum[j][0]*normptr[k];
- g+=oct.light[k].accum[j][1]*normptr[k];
- b+=oct.light[k].accum[j][2]*normptr[k];
- }
+ uint8_t *iptr=&lptr[ofs+lchild_offsets[j]];
+
+ float r=oct.light_accum[j][0]*norm;
+ float g=oct.light_accum[j][1]*norm;
+ float b=oct.light_accum[j][2]*norm;
r=pow(r*mult,gamma);
g=pow(g*mult,gamma);
b=pow(b*mult,gamma);
+ double gray = (r+g+b)/3.0;
+ r = gray + (r-gray)*saturation;
+ g = gray + (g-gray)*saturation;
+ b = gray + (b-gray)*saturation;
+
float ic[3]={
r,
g,
@@ -1757,6 +2015,8 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) {
} else {
+ int ofs = (oct.texture_y * baked_octree_texture_w + oct.texture_x)<<2;
+ ERR_CONTINUE(ofs<0 || ofs >len);
//write indices
for(int j=0;j<8;j++) {
@@ -1822,49 +2082,61 @@ void BakedLightBaker::_bake_thread_func(void *arg) {
BakedLightBaker *ble = (BakedLightBaker*)arg;
- ble->rays_at_snap_time=ble->total_rays;
- ble->snap_time=OS::get_singleton()->get_ticks_usec();
- while(!ble->bake_thread_exit) {
- ble->throw_rays(1000);
- uint64_t t=OS::get_singleton()->get_ticks_usec();
- if (t-ble->snap_time>1000000) {
+ ThreadStack thread_stack;
- double time = (t-ble->snap_time)/1000000.0;
+ thread_stack.ray_stack = memnew_arr(uint32_t,ble->bvh_depth);
+ thread_stack.bvh_stack = memnew_arr(BVH*,ble->bvh_depth);
+ thread_stack.octant_stack = memnew_arr(uint32_t,ble->octree_depth*2 );
+ thread_stack.octantptr_stack = memnew_arr(uint32_t,ble->octree_depth*2 );
- int rays=ble->total_rays-ble->rays_at_snap_time;
- ble->rays_sec=int(rays/time);
- ble->snap_time=OS::get_singleton()->get_ticks_usec();
- ble->rays_at_snap_time=ble->total_rays;
- }
+ while(!ble->bake_thread_exit) {
+
+ ble->throw_rays(thread_stack,1000);
}
+ memdelete_arr(thread_stack.ray_stack );
+ memdelete_arr(thread_stack.bvh_stack );
+ memdelete_arr(thread_stack.octant_stack );
+ memdelete_arr(thread_stack.octantptr_stack );
+
}
void BakedLightBaker::_start_thread() {
- if (thread!=NULL)
+ if (threads.size()!=0)
return;
bake_thread_exit=false;
- thread=Thread::create(_bake_thread_func,this);
+ int thread_count = EDITOR_DEF("light_baker/custom_bake_threads",0);
+ if (thread_count<=0 || thread_count>64)
+ thread_count=OS::get_singleton()->get_processor_count();
+
+ //thread_count=1;
+ threads.resize(thread_count);
+ for(int i=0;i<threads.size();i++) {
+ threads[i]=Thread::create(_bake_thread_func,this);
+ }
}
void BakedLightBaker::_stop_thread() {
- if (thread==NULL)
+ if (threads.size()==0)
return;
bake_thread_exit=true;
- Thread::wait_to_finish(thread);
- thread=NULL;
+ for(int i=0;i<threads.size();i++) {
+ Thread::wait_to_finish(threads[i]);
+ }
+ threads.clear();
}
void BakedLightBaker::_plot_pixel_to_lightmap(int x, int y, int width, int height, uint8_t *image, const Vector3& p_pos,const Vector3& p_normal,double *p_norm_ptr,float mult,float gamma) {
uint8_t *ptr = &image[(y*width+x)*4];
- int lc = lights.size();
+ //int lc = lights.size();
+ double norm = 1.0/double(total_rays);
Color color;
@@ -1888,11 +2160,9 @@ void BakedLightBaker::_plot_pixel_to_lightmap(int x, int y, int width, int heigh
for(int i=0;i<8;i++) {
- for(int j=0;j<lc;j++) {
- cols[i].x+=octant.light[j].accum[i][0]*p_norm_ptr[j];
- cols[i].y+=octant.light[j].accum[i][1]*p_norm_ptr[j];
- cols[i].z+=octant.light[j].accum[i][2]*p_norm_ptr[j];
- }
+ cols[i].x+=octant.light_accum[i][0]*norm;
+ cols[i].y+=octant.light_accum[i][1]*norm;
+ cols[i].z+=octant.light_accum[i][2]*norm;
}
@@ -2355,12 +2625,13 @@ void BakedLightBaker::clear() {
memdelete_arr(octantptr_stack);
if (bvh_stack)
memdelete_arr(bvh_stack);
-
+/*
+ * ???
for(int i=0;i<octant_pool.size();i++) {
- if (octant_pool[i].leaf) {
- memdelete_arr( octant_pool[i].light );
- } Vector<double> norm_arr;
- norm_arr.resize(lights.size());
+ //if (octant_pool[i].leaf) {
+ // memdelete_arr( octant_pool[i].light );
+ //} Vector<double> norm_arr;
+ //norm_arr.resize(lights.size());
for(int i=0;i<lights.size();i++) {
norm_arr[i] = 1.0/get_normalization(i);
@@ -2368,6 +2639,7 @@ void BakedLightBaker::clear() {
const double *normptr=norm_arr.ptr();
}
+*/
octant_pool.clear();
octant_pool_size=0;
bvh=NULL;
@@ -2388,8 +2660,9 @@ void BakedLightBaker::clear() {
baked_octree_texture_h=0;
paused=false;
baking=false;
- thread=NULL;
+
bake_thread_exit=false;
+ first_bake_to_map=true;
baked_light=Ref<BakedLight>();
total_rays=0;
@@ -2414,12 +2687,11 @@ BakedLightBaker::BakedLightBaker() {
baked_octree_texture_h=0;
paused=false;
baking=false;
- thread=NULL;
+
bake_thread_exit=false;
- rays_at_snap_time=0;
- snap_time=0;
- rays_sec=0;
total_rays=0;
+ first_bake_to_map=true;
+ linear_color=false;
}
diff --git a/tools/editor/plugins/baked_light_baker.h b/tools/editor/plugins/baked_light_baker.h
index e0a9d91cd4..8fbeeddc6a 100644
--- a/tools/editor/plugins/baked_light_baker.h
+++ b/tools/editor/plugins/baked_light_baker.h
@@ -15,17 +15,19 @@ public:
OCTANT_POOL_CHUNK=1000000
};
- struct OctantLight {
+ //struct OctantLight {
- double accum[8][3];
- };
+ // double accum[8][3];
+ //};
struct Octant {
bool leaf;
AABB aabb;
uint16_t texture_x;
uint16_t texture_y;
+ int sampler_ofs;
float normal_accum[8][3];
+ double full_accum[3];
int parent;
union {
struct {
@@ -33,7 +35,7 @@ public:
float offset[3];
int bake_neighbour;
bool first_neighbour;
- OctantLight *light;
+ double light_accum[8][3];
};
int children[8];
};
@@ -234,32 +236,49 @@ public:
Transform base_inv;
int leaf_list;
int octree_depth;
+ int bvh_depth;
int cell_count;
uint32_t *ray_stack;
+ BVH **bvh_stack;
uint32_t *octant_stack;
uint32_t *octantptr_stack;
+
+ struct ThreadStack {
+ uint32_t *octant_stack;
+ uint32_t *octantptr_stack;
+ uint32_t *ray_stack;
+ BVH **bvh_stack;
+ };
+
Map<Vector3,Vector3> endpoint_normal;
Map<Vector3,uint64_t> endpoint_normal_bits;
- BVH **bvh_stack;
+
float cell_size;
float plot_size; //multiplied by cell size
float octree_extra_margin;
int max_bounces;
- uint64_t total_rays;
+ int64_t total_rays;
bool use_diffuse;
bool use_specular;
bool use_translucency;
+ bool linear_color;
int baked_octree_texture_w;
int baked_octree_texture_h;
+ int baked_light_texture_w;
+ int baked_light_texture_h;
int lattice_size;
float edge_damp;
float normal_damp;
+ float tint;
+ float ao_radius;
+ float ao_strength;
bool paused;
bool baking;
+ bool first_bake_to_map;
Map<Ref<Material>,MeshMaterial*> mat_map;
Map<Ref<Texture>,MeshTexture*> tex_map;
@@ -285,19 +304,16 @@ public:
//void _plot_light(const Vector3& p_plot_pos,const AABB& p_plot_aabb,const Color& p_light,int p_octant=0);
- void _plot_light(int p_light_index,const Vector3& p_plot_pos,const AABB& p_plot_aabb,const Color& p_light,const Plane& p_plane);
+ void _plot_light(ThreadStack& thread_stack,const Vector3& p_plot_pos,const AABB& p_plot_aabb,const Color& p_light,const Color& p_tint_light,bool p_only_full,const Plane& p_plane);
//void _plot_light_point(const Vector3& p_plot_pos, Octant *p_octant, const AABB& p_aabb,const Color& p_light);
- float _throw_ray(int p_light_index,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce=false,bool p_only_dist=false);
+ float _throw_ray(ThreadStack& thread_stack,bool p_bake_direct,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce=false,bool p_only_dist=false);
float total_light_area;
- uint64_t rays_at_snap_time;
- uint64_t snap_time;
- int rays_sec;
+ Vector<Thread*> threads;
- Thread *thread;
bool bake_thread_exit;
static void _bake_thread_func(void *arg);
@@ -306,18 +322,20 @@ public:
public:
- void throw_rays(int p_amount);
+ void throw_rays(ThreadStack &thread_stack, int p_amount);
double get_normalization(int p_light_idx) const;
+ double get_modifier(int p_light_idx) const;
void bake(const Ref<BakedLight>& p_light,Node *p_base);
bool is_baking();
void set_pause(bool p_pause);
bool is_paused();
- int get_rays_sec() { return rays_sec; }
+ uint64_t get_rays_thrown() { return total_rays; }
Error transfer_to_lightmaps();
- void update_octree_image(DVector<uint8_t> &p_image);
+ void update_octree_sampler(DVector<int> &p_sampler);
+ void update_octree_images(DVector<uint8_t> &p_octree,DVector<uint8_t> &p_light);
Ref<BakedLight> get_baked_light() { return baked_light; }
diff --git a/tools/editor/plugins/baked_light_baker_cmpxchg.cpp b/tools/editor/plugins/baked_light_baker_cmpxchg.cpp
new file mode 100644
index 0000000000..d08c9f6484
--- /dev/null
+++ b/tools/editor/plugins/baked_light_baker_cmpxchg.cpp
@@ -0,0 +1,84 @@
+
+#include "typedefs.h"
+
+
+#ifdef WINDOWS_ENABLED
+
+#include "windows.h"
+
+void baked_light_baker_add_64f(double *dst,double value) {
+
+ union {
+ int64_t i;
+ double f;
+ } swapy;
+
+
+ while(true) {
+ swapy.f=*dst;
+ int64_t from = swapy.i;
+ swapy.f+=value;
+ int64_t to=swapy.i;
+ int64_t result = InterlockedCompareExchange64((int64_t*)dst,to,from);
+ if (result==from)
+ break;
+ }
+
+}
+
+void baked_light_baker_add_64i(int64_t *dst,int64_t value) {
+
+ while(true) {
+ int64_t from = *dst;
+ int64_t to = from+value;
+ int64_t result = InterlockedCompareExchange64(dst,to,from);
+ if (result==from)
+ break;
+ }
+}
+
+#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
+
+void baked_light_baker_add_64f(double *dst,double value) {
+
+
+ union {
+ int64_t i;
+ double f;
+ } swapy;
+
+
+ while(true) {
+ swapy.f=*dst;
+ int64_t from = swapy.i;
+ swapy.f+=value;
+ int64_t to=swapy.i;
+ if (__sync_bool_compare_and_swap((int64_t*)dst,from,to))
+ break;
+ }
+}
+
+void baked_light_baker_add_64i(int64_t *dst,int64_t value) {
+
+ while(!__sync_bool_compare_and_swap(dst,*dst,(*dst)+value)) {}
+
+}
+
+#else
+
+//in goder (the god of programmers) we trust
+#warning seems this platform or compiler does not support safe cmpxchg, your baked lighting may be funny
+
+void baked_light_baker_add_64f(double *dst,double value) {
+
+ *dst+=value;
+
+}
+
+void baked_light_baker_add_64i(int64_t *dst,int64_t value) {
+
+ *dst+=value;
+
+}
+
+#endif
diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/tools/editor/plugins/baked_light_editor_plugin.cpp
index 3d48f2e732..2f8393f102 100644
--- a/tools/editor/plugins/baked_light_editor_plugin.cpp
+++ b/tools/editor/plugins/baked_light_editor_plugin.cpp
@@ -111,7 +111,10 @@ void BakedLightEditor::_notification(int p_option) {
#endif
ERR_FAIL_COND(node->get_baked_light().is_null());
- baker->update_octree_image(octree_texture);
+ baker->update_octree_images(octree_texture,light_texture);
+ baker->update_octree_sampler(octree_sampler);
+ // print_line("sampler size: "+itos(octree_sampler.size()*4));
+
#if 1
//debug
Image img(baker->baked_octree_texture_w,baker->baked_octree_texture_h,0,Image::FORMAT_RGBA,octree_texture);
@@ -121,11 +124,19 @@ void BakedLightEditor::_notification(int p_option) {
#endif
- bake_info->set_text("rays/s: "+itos(baker->get_rays_sec()));
+
+
+ uint64_t rays_snap = baker->get_rays_thrown();
+ int rays_sec = (rays_snap-last_rays_time)*1.0-(update_timeout);
+ last_rays_time=rays_snap;
+
+ bake_info->set_text("rays/s: "+itos(rays_sec));
update_timeout=1;
print_line("MSUPDATE: "+itos(OS::get_singleton()->get_ticks_msec()-t));
t=OS::get_singleton()->get_ticks_msec();
node->get_baked_light()->set_octree(octree_texture);
+ node->get_baked_light()->set_light(light_texture);
+ node->get_baked_light()->set_sampler_octree(octree_sampler);
node->get_baked_light()->set_edited(true);
print_line("MSSET: "+itos(OS::get_singleton()->get_ticks_msec()-t));
@@ -195,6 +206,9 @@ void BakedLightEditor::_bake_pressed() {
baker->bake(node->get_baked_light(),node);
node->get_baked_light()->set_mode(BakedLight::MODE_OCTREE);
update_timeout=0;
+
+ last_rays_time=0;
+
set_process(true);
}
diff --git a/tools/editor/plugins/baked_light_editor_plugin.h b/tools/editor/plugins/baked_light_editor_plugin.h
index 7912bd92e5..27ab88d70b 100644
--- a/tools/editor/plugins/baked_light_editor_plugin.h
+++ b/tools/editor/plugins/baked_light_editor_plugin.h
@@ -23,6 +23,8 @@ class BakedLightEditor : public Control {
float update_timeout;
DVector<uint8_t> octree_texture;
+ DVector<uint8_t> light_texture;
+ DVector<int> octree_sampler;
BakedLightBaker *baker;
AcceptDialog *err_dialog;
@@ -33,6 +35,9 @@ class BakedLightEditor : public Control {
Button *button_make_lightmaps;
Label *bake_info;
+ uint64_t last_rays_time;
+
+
BakedLightInstance *node;
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index 074fa5c946..e91e7a94fe 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -1971,7 +1971,7 @@ void SpatialEditorViewport::_preview_exited_scene() {
void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
- uint32_t layer=1<<(GIZMO_BASE_LAYER+p_idx)|(1<<GIZMO_GRID_LAYER);
+ uint32_t layer=1<<(GIZMO_BASE_LAYER+p_idx);//|(1<<GIZMO_GRID_LAYER);
for(int i=0;i<3;i++) {
move_gizmo_instance[i]=VS::get_singleton()->instance_create();
diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py
index 7899098e3d..a92b97b8a9 100644
--- a/tools/export/blender25/io_scene_dae/export_dae.py
+++ b/tools/export/blender25/io_scene_dae/export_dae.py
@@ -485,9 +485,17 @@ class DaeExporter:
uv_layer_count=len(mesh.uv_textures)
if (len(mesh.uv_textures)):
- mesh.calc_tangents()
+ try:
+ mesh.calc_tangents()
+ except:
+ print("Warning, blender API is fucked up, not exporting UVs for this object.")
+ uv_layer_count=0
+ mesh.calc_normals_split()
+ has_tangents=False
+
else:
mesh.calc_normals_split()
+ has_tangents=False
for fi in range(len(mesh.polygons)):