-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
This commit is contained in:
parent
9608d4255e
commit
e82dc40205
|
@ -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')
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Binary file not shown.
|
@ -5363,6 +5363,18 @@ Variant RasterizerGLES1::environment_fx_get_param(RID p_env,VS::EnvironmentFxPar
|
|||
ERR_FAIL_COND_V(!env,Variant());
|
||||
return env->fx_param[p_param];
|
||||
|
||||
}
|
||||
|
||||
/* 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*/
|
||||
|
@ -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 );
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
{
|
||||
|
|
|
@ -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*/
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ sources = [
|
|||
"theora/video_stream_theora.cpp",
|
||||
]
|
||||
|
||||
env.drivers_sources += sources
|
||||
if env['use_theoraplayer_binary'] != "yes":
|
||||
env.drivers_sources += sources
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
Node *subexpr=NULL;
|
||||
|
||||
subexpr = _parse_and_reduce_expression(p_class,false);
|
||||
if (!subexpr)
|
||||
return;
|
||||
|
||||
if (autoexport) {
|
||||
if (subexpr->type==Node::TYPE_ARRAY) {
|
||||
|
||||
member._export.type=Variant::ARRAY;
|
||||
|
||||
} else if (subexpr->type==Node::TYPE_DICTIONARY) {
|
||||
|
||||
member._export.type=Variant::DICTIONARY;
|
||||
|
||||
} else {
|
||||
|
||||
if (subexpr->type!=Node::TYPE_CONSTANT) {
|
||||
|
||||
_set_error("Type-less export needs a constant expression assigned to infer type.");
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
member.default_value=cn->value;
|
||||
}
|
||||
}
|
||||
#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) {
|
||||
|
||||
_set_error("Type-less export needs a constant expression assigned to infer type.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
#ifdef DEBUG_ENABLED
|
||||
int line = tokenizer->get_token_line();
|
||||
#endif
|
||||
tokenizer->advance();
|
||||
|
||||
Node *subexpr=NULL;
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_PR_SETGET) {
|
||||
|
||||
subexpr = _parse_and_reduce_expression(p_class,false);
|
||||
if (!subexpr)
|
||||
return;
|
||||
|
||||
if (autoexport) {
|
||||
if (subexpr->type==Node::TYPE_ARRAY) {
|
||||
tokenizer->advance();
|
||||
|
||||
p_class->variables[p_class->variables.size()-1]._export.type=Variant::ARRAY;
|
||||
|
||||
} else if (subexpr->type==Node::TYPE_DICTIONARY) {
|
||||
|
||||
p_class->variables[p_class->variables.size()-1]._export.type=Variant::DICTIONARY;
|
||||
|
||||
} else {
|
||||
|
||||
if (subexpr->type!=Node::TYPE_CONSTANT) {
|
||||
|
||||
_set_error("Type-less export needs a constant expression assigned to infer type.");
|
||||
return;
|
||||
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'.");
|
||||
}
|
||||
|
||||
ConstantNode *cn = static_cast<ConstantNode*>(subexpr);
|
||||
if (cn->value.get_type()==Variant::NIL) {
|
||||
member.setter=tokenizer->get_token_identifier();
|
||||
|
||||
_set_error("Can't accept a null constant expression for infering export type.");
|
||||
return;
|
||||
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 ','.");
|
||||
}
|
||||
p_class->variables[p_class->variables.size()-1]._export.type=cn->value.get_type();
|
||||
|
||||
member.getter=tokenizer->get_token_identifier();
|
||||
tokenizer->advance();
|
||||
|
||||
}
|
||||
}
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (subexpr->type==Node::TYPE_CONSTANT && p_class->variables[p_class->variables.size()-1]._export.type!=Variant::NIL) {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
#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);
|
||||
p_class->variables.push_back(member);
|
||||
|
||||
_end_statement();
|
||||
|
||||
|
|
|
@ -82,6 +82,8 @@ public:
|
|||
Variant default_value;
|
||||
#endif
|
||||
StringName identifier;
|
||||
StringName setter;
|
||||
StringName getter;
|
||||
};
|
||||
struct Constant {
|
||||
StringName identifier;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'])
|
||||
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -47,6 +47,7 @@ class VisualInstance : public Spatial {
|
|||
|
||||
RID _get_visual_instance_rid() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//intensity*=1.0-Math::abs(p_plane.distance_to(pos))/(plot_size*cell_size);
|
||||
//intensity = Math::cos(d*Math_PI*0.5/r);
|
||||
|
||||
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;
|
||||
|
||||
if (!p_first_bounce) {
|
||||
bool skip=false;
|
||||
|
||||
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,9 +1366,87 @@ void BakedLightBaker::_make_octree_texture() {
|
|||
|
||||
//ok let's try to just create a texture
|
||||
|
||||
int otex_w=256;
|
||||
|
||||
while (true) {
|
||||
|
||||
|
||||
|
||||
uint32_t oct_idx=leaf_list;
|
||||
|
||||
int row=0;
|
||||
|
||||
|
||||
print_line("begin at row "+itos(row));
|
||||
int longest_line_reused=0;
|
||||
int col=0;
|
||||
int processed=0;
|
||||
|
||||
//reset
|
||||
while(oct_idx) {
|
||||
|
||||
BakedLightBaker::Octant *oct = &octants[oct_idx];
|
||||
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;
|
||||
}
|
||||
|
||||
row+=4;
|
||||
|
||||
if (otex_w < row) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
|
||||
int otex_w=(1<<lattice_size)*(1<<lattice_size)*2; //make sure lattice fits horizontally
|
||||
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++) {
|
||||
|
||||
|
@ -1320,64 +1459,7 @@ void BakedLightBaker::_make_octree_texture() {
|
|||
|
||||
//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);
|
||||
|
||||
|
||||
uint32_t oct_idx=leaf_list;
|
||||
|
||||
//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;
|
||||
|
||||
|
||||
print_line("begin at row "+itos(row));
|
||||
int longest_line_reused=0;
|
||||
int col=0;
|
||||
int processed=0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
print_line("processed "+itos(processed));
|
||||
|
||||
print_line("longest reused: "+itos(longest_line_reused));
|
||||
|
||||
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;
|
||||
uint8_t *iptr=&lptr[ofs+lchild_offsets[j]];
|
||||
|
||||
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];
|
||||
}
|
||||
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();
|
||||
|
||||
|
||||
ThreadStack thread_stack;
|
||||
|
||||
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 );
|
||||
|
||||
while(!ble->bake_thread_exit) {
|
||||
|
||||
ble->throw_rays(1000);
|
||||
uint64_t t=OS::get_singleton()->get_ticks_usec();
|
||||
if (t-ble->snap_time>1000000) {
|
||||
|
||||
double time = (t-ble->snap_time)/1000000.0;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)):
|
||||
|
|
Loading…
Reference in New Issue