diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2017-01-02 21:38:20 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2017-01-02 21:52:26 +0100 |
commit | 3f3f5a5359973e95e94148676a9793d6f52468f3 (patch) | |
tree | 65adf17c3d3f8d3a83bec29f51142fe884e942d8 /scene | |
parent | db46a344180d4eae1455e97e22bf84c9c304be7c (diff) | |
parent | 2820b2d82b2ed747011e37c543aefc6d4d4edee9 (diff) |
Merge remote-tracking branch 'origin/gles3' into gles3-on-master
Various merge conflicts have been fixed manually and some mistakes
might have been made - time will tell :)
Diffstat (limited to 'scene')
81 files changed, 7830 insertions, 3858 deletions
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 5d0d611917..aba2175fda 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -42,9 +42,6 @@ bool CanvasItemMaterial::_set(const StringName& p_name, const Variant& p_value) if (p_name==SceneStringNames::get_singleton()->shader_shader) { set_shader(p_value); return true; - } else if (p_name==SceneStringNames::get_singleton()->shading_mode) { - set_shading_mode(ShadingMode(p_value.operator int())); - return true; } else { if (shader.is_valid()) { @@ -58,7 +55,7 @@ bool CanvasItemMaterial::_set(const StringName& p_name, const Variant& p_value) } } if (pr) { - VisualServer::get_singleton()->canvas_item_material_set_shader_param(material,pr,p_value); + VisualServer::get_singleton()->material_set_param(_get_material(),pr,p_value); return true; } } @@ -74,18 +71,14 @@ bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const { r_ret=get_shader(); return true; - } else if (p_name==SceneStringNames::get_singleton()->shading_mode) { - - r_ret=shading_mode; - return true; } else { if (shader.is_valid()) { StringName pr = shader->remap_param(p_name); if (pr) { - r_ret=VisualServer::get_singleton()->canvas_item_material_get_shader_param(material,pr); + r_ret=VisualServer::get_singleton()->material_get_param(_get_material(),pr); return true; } } @@ -100,7 +93,6 @@ bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const { void CanvasItemMaterial::_get_property_list( List<PropertyInfo> *p_list) const { p_list->push_back( PropertyInfo( Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE,"CanvasItemShader,CanvasItemShaderGraph" ) ); - p_list->push_back( PropertyInfo( Variant::INT, "shader/shading_mode",PROPERTY_HINT_ENUM,"Normal,Unshaded,Light Only") ); if (!shader.is_null()) { @@ -119,7 +111,7 @@ void CanvasItemMaterial::set_shader(const Ref<Shader>& p_shader) { if (shader.is_valid()) rid=shader->get_rid(); - VS::get_singleton()->canvas_item_material_set_shader(material,rid); + VS::get_singleton()->material_set_shader(_get_material(),rid); _change_notify(); //properties for shader exposed emit_changed(); } @@ -131,28 +123,14 @@ Ref<Shader> CanvasItemMaterial::get_shader() const{ void CanvasItemMaterial::set_shader_param(const StringName& p_param,const Variant& p_value){ - VS::get_singleton()->canvas_item_material_set_shader_param(material,p_param,p_value); + VS::get_singleton()->material_set_param(_get_material(),p_param,p_value); } Variant CanvasItemMaterial::get_shader_param(const StringName& p_param) const{ - return VS::get_singleton()->canvas_item_material_get_shader_param(material,p_param); + return VS::get_singleton()->material_get_param(_get_material(),p_param); } -RID CanvasItemMaterial::get_rid() const { - - return material; -} - -void CanvasItemMaterial::set_shading_mode(ShadingMode p_mode) { - - shading_mode=p_mode; - VS::get_singleton()->canvas_item_material_set_shading_mode(material,VS::CanvasItemShadingMode(p_mode)); -} - -CanvasItemMaterial::ShadingMode CanvasItemMaterial::get_shading_mode() const { - return shading_mode; -} void CanvasItemMaterial::_bind_methods() { @@ -161,12 +139,7 @@ void CanvasItemMaterial::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_shader:Shader"),&CanvasItemMaterial::get_shader); ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItemMaterial::set_shader_param); ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItemMaterial::get_shader_param); - ObjectTypeDB::bind_method(_MD("set_shading_mode","mode"),&CanvasItemMaterial::set_shading_mode); - ObjectTypeDB::bind_method(_MD("get_shading_mode"),&CanvasItemMaterial::get_shading_mode); - BIND_CONSTANT( SHADING_NORMAL ); - BIND_CONSTANT( SHADING_UNSHADED ); - BIND_CONSTANT( SHADING_ONLY_LIGHT ); } @@ -189,13 +162,13 @@ void CanvasItemMaterial::get_argument_options(const StringName& p_function,int p CanvasItemMaterial::CanvasItemMaterial() { - material=VS::get_singleton()->canvas_item_material_create(); - shading_mode=SHADING_NORMAL; + + } CanvasItemMaterial::~CanvasItemMaterial(){ - VS::get_singleton()->free(material); + } @@ -369,6 +342,8 @@ Matrix32 CanvasItem::get_global_transform_with_canvas() const { return last_valid->canvas_layer->get_transform() * xform; else if (is_inside_tree()) return get_viewport()->get_canvas_transform() * xform; + + return xform; } Matrix32 CanvasItem::get_global_transform() const { @@ -389,42 +364,17 @@ Matrix32 CanvasItem::get_global_transform() const { } - -void CanvasItem::_queue_sort_children() { - - if (pending_children_sort) - return; - - pending_children_sort=true; - MessageQueue::get_singleton()->push_call(this,"_sort_children"); -} - -void CanvasItem::_sort_children() { - - pending_children_sort=false; +void CanvasItem::_toplevel_raise_self() { if (!is_inside_tree()) return; - for(int i=0;i<get_child_count();i++) { - - Node *n = get_child(i); - CanvasItem *ci=n->cast_to<CanvasItem>(); - - if (ci) { - if (ci->toplevel || ci->group!="") - continue; - VisualServer::get_singleton()->canvas_item_raise(n->cast_to<CanvasItem>()->canvas_item); - } - } -} - -void CanvasItem::_raise_self() { + if (canvas_layer) + VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item,canvas_layer->get_sort_index()); + else + VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item,get_viewport()->gui_get_canvas_sort_index()); - if (!is_inside_tree()) - return; - VisualServer::get_singleton()->canvas_item_raise(canvas_item); } @@ -456,14 +406,19 @@ void CanvasItem::_enter_canvas() { group = "root_canvas"+itos(canvas.get_id()); add_to_group(group); - get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_raise_self"); + if (canvas_layer) + canvas_layer->reset_sort_index(); + else + get_viewport()->gui_reset_canvas_sort_index(); + + get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_toplevel_raise_self"); } else { CanvasItem *parent = get_parent_item(); canvas_layer=parent->canvas_layer; VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,parent->get_canvas_item()); - parent->_queue_sort_children(); + VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item,get_index()); } pending_update=false; @@ -490,7 +445,6 @@ void CanvasItem::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { first_draw=true; - pending_children_sort=false; if (get_parent()) { CanvasItem *ci = get_parent()->cast_to<CanvasItem>(); if (ci) @@ -503,13 +457,15 @@ void CanvasItem::_notification(int p_what) { } break; case NOTIFICATION_MOVED_IN_PARENT: { + if (!is_inside_tree()) + break; if (group!="") { - get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_raise_self"); + get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_toplevel_raise_self"); } else { CanvasItem *p = get_parent_item(); ERR_FAIL_COND(!p); - p->_queue_sort_children(); + VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item,get_index()); } @@ -564,15 +520,15 @@ void CanvasItem::update() { MessageQueue::get_singleton()->push_call(this,"_update_callback"); } -void CanvasItem::set_opacity(float p_opacity) { +void CanvasItem::set_modulate(const Color& p_modulate) { - opacity=p_opacity; - VisualServer::get_singleton()->canvas_item_set_opacity(canvas_item,opacity); + modulate=p_modulate; + VisualServer::get_singleton()->canvas_item_set_modulate(canvas_item,modulate); } -float CanvasItem::get_opacity() const { +Color CanvasItem::get_modulate() const { - return opacity; + return modulate; } @@ -609,29 +565,17 @@ CanvasItem *CanvasItem::get_parent_item() const { } -void CanvasItem::set_self_opacity(float p_self_opacity) { +void CanvasItem::set_self_modulate(const Color& p_self_modulate) { - self_opacity=p_self_opacity; - VisualServer::get_singleton()->canvas_item_set_self_opacity(canvas_item,self_opacity); + self_modulate=p_self_modulate; + VisualServer::get_singleton()->canvas_item_set_self_modulate(canvas_item,self_modulate); } -float CanvasItem::get_self_opacity() const { +Color CanvasItem::get_self_modulate() const { - return self_opacity; + return self_modulate; } -void CanvasItem::set_blend_mode(BlendMode p_blend_mode) { - - ERR_FAIL_INDEX(p_blend_mode,5); - blend_mode=p_blend_mode; - VisualServer::get_singleton()->canvas_item_set_blend_mode(canvas_item,VS::MaterialBlendMode(blend_mode)); - -} - -CanvasItem::BlendMode CanvasItem::get_blend_mode() const { - - return blend_mode; -} void CanvasItem::set_light_mask(int p_light_mask) { @@ -908,7 +852,7 @@ void CanvasItem::set_draw_behind_parent(bool p_enable) { if (behind==p_enable) return; behind=p_enable; - VisualServer::get_singleton()->canvas_item_set_on_top(canvas_item,!behind); + VisualServer::get_singleton()->canvas_item_set_draw_behind_parent(canvas_item,behind); } @@ -978,8 +922,7 @@ Vector2 CanvasItem::get_local_mouse_pos() const{ void CanvasItem::_bind_methods() { - ObjectTypeDB::bind_method(_MD("_sort_children"),&CanvasItem::_sort_children); - ObjectTypeDB::bind_method(_MD("_raise_self"),&CanvasItem::_raise_self); + ObjectTypeDB::bind_method(_MD("_toplevel_raise_self"),&CanvasItem::_toplevel_raise_self); ObjectTypeDB::bind_method(_MD("_update_callback"),&CanvasItem::_update_callback); ObjectTypeDB::bind_method(_MD("_set_visible_"),&CanvasItem::_set_visible_); ObjectTypeDB::bind_method(_MD("_is_visible_"),&CanvasItem::_is_visible_); @@ -1006,16 +949,13 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_as_toplevel","enable"),&CanvasItem::set_as_toplevel); ObjectTypeDB::bind_method(_MD("is_set_as_toplevel"),&CanvasItem::is_set_as_toplevel); - ObjectTypeDB::bind_method(_MD("set_blend_mode","blend_mode"),&CanvasItem::set_blend_mode); - ObjectTypeDB::bind_method(_MD("get_blend_mode"),&CanvasItem::get_blend_mode); - ObjectTypeDB::bind_method(_MD("set_light_mask","light_mask"),&CanvasItem::set_light_mask); ObjectTypeDB::bind_method(_MD("get_light_mask"),&CanvasItem::get_light_mask); - ObjectTypeDB::bind_method(_MD("set_opacity","opacity"),&CanvasItem::set_opacity); - ObjectTypeDB::bind_method(_MD("get_opacity"),&CanvasItem::get_opacity); - ObjectTypeDB::bind_method(_MD("set_self_opacity","self_opacity"),&CanvasItem::set_self_opacity); - ObjectTypeDB::bind_method(_MD("get_self_opacity"),&CanvasItem::get_self_opacity); + ObjectTypeDB::bind_method(_MD("set_modulate","modulate"),&CanvasItem::set_modulate); + ObjectTypeDB::bind_method(_MD("get_modulate"),&CanvasItem::get_modulate); + ObjectTypeDB::bind_method(_MD("set_self_modulate","self_modulate"),&CanvasItem::set_self_modulate); + ObjectTypeDB::bind_method(_MD("get_self_modulate"),&CanvasItem::get_self_modulate); ObjectTypeDB::bind_method(_MD("set_draw_behind_parent","enable"),&CanvasItem::set_draw_behind_parent); ObjectTypeDB::bind_method(_MD("is_draw_behind_parent_enabled"),&CanvasItem::is_draw_behind_parent_enabled); @@ -1064,12 +1004,11 @@ void CanvasItem::_bind_methods() { BIND_VMETHOD(MethodInfo("_draw")); ADD_PROPERTYNO( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"),_SCS("_is_visible_") ); - ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_opacity"),_SCS("get_opacity") ); - ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/self_opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_self_opacity"),_SCS("get_self_opacity") ); + ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/modulate",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_modulate"),_SCS("get_modulate") ); + ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/self_modulate",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_self_modulate"),_SCS("get_self_modulate") ); ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"visibility/behind_parent"), _SCS("set_draw_behind_parent"),_SCS("is_draw_behind_parent_enabled") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility - ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") ); ADD_PROPERTYNO( PropertyInfo(Variant::INT,"visibility/light_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"),_SCS("get_light_mask") ); ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"material/material",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"), _SCS("set_material"),_SCS("get_material") ); ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"material/use_parent"), _SCS("set_use_parent_material"),_SCS("get_use_parent_material") ); @@ -1171,12 +1110,10 @@ CanvasItem::CanvasItem() : xform_change(this) { canvas_item=VisualServer::get_singleton()->canvas_item_create(); hidden=false; pending_update=false; - opacity=1; - self_opacity=1; + modulate=Color(1,1,1,1); + self_modulate=Color(1,1,1,1); toplevel=false; - pending_children_sort=false; first_draw=false; - blend_mode=BLEND_MODE_MIX; drawing=false; behind=false; block_transform_notify=false; diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 2289e26653..e6abc891c7 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -33,6 +33,7 @@ #include "scene/resources/texture.h" #include "scene/main/scene_main_loop.h" #include "scene/resources/shader.h" +#include "scene/resources/material.h" class CanvasLayer; class Viewport; @@ -40,22 +41,18 @@ class Font; class StyleBox; -class CanvasItemMaterial : public Resource{ +class CanvasItemMaterial : public Material { - OBJ_TYPE(CanvasItemMaterial,Resource); - RID material; + OBJ_TYPE(CanvasItemMaterial,Material); Ref<Shader> shader; public: - enum ShadingMode { + /*enum ShadingMode { SHADING_NORMAL, SHADING_UNSHADED, SHADING_ONLY_LIGHT, - }; + };*/ protected: - - ShadingMode shading_mode; - bool _set(const StringName& p_name, const Variant& p_value); bool _get(const StringName& p_name,Variant &r_ret) const; void _get_property_list( List<PropertyInfo> *p_list) const; @@ -72,15 +69,11 @@ public: void set_shader_param(const StringName& p_param,const Variant& p_value); Variant get_shader_param(const StringName& p_param) const; - void set_shading_mode(ShadingMode p_mode); - ShadingMode get_shading_mode() const; - - virtual RID get_rid() const; CanvasItemMaterial(); ~CanvasItemMaterial(); }; -VARIANT_ENUM_CAST( CanvasItemMaterial::ShadingMode ); + class CanvasItem : public Node { @@ -107,20 +100,18 @@ private: CanvasLayer *canvas_layer; - float opacity; - float self_opacity; + Color modulate; + Color self_modulate; List<CanvasItem*> children_items; List<CanvasItem*>::Element *C; - BlendMode blend_mode; int light_mask; bool first_draw; bool hidden; bool pending_update; bool toplevel; - bool pending_children_sort; bool drawing; bool block_transform_notify; bool behind; @@ -133,7 +124,7 @@ private: mutable bool global_invalid; - void _raise_self(); + void _toplevel_raise_self(); void _propagate_visibility_changed(bool p_visible); @@ -145,9 +136,6 @@ private: void _enter_canvas(); void _exit_canvas(); - void _queue_sort_children(); - void _sort_children(); - void _notify_transform(CanvasItem *p_node); void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); } @@ -193,17 +181,14 @@ public: void update(); - virtual void set_blend_mode(BlendMode p_blend_mode); - BlendMode get_blend_mode() const; - virtual void set_light_mask(int p_light_mask); int get_light_mask() const; - void set_opacity(float p_opacity); - float get_opacity() const; + void set_modulate(const Color& p_modulate); + Color get_modulate() const; - void set_self_opacity(float p_self_opacity); - float get_self_opacity() const; + void set_self_modulate(const Color& p_self_modulate); + Color get_self_modulate() const; /* DRAWING API */ diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 11ae6c3d32..e5b0d54376 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -235,26 +235,26 @@ int Light2D::get_layer_range_max() const { return layer_max; } -void Light2D::set_item_mask( int p_mask) { +void Light2D::set_item_cull_mask( int p_mask) { item_mask=p_mask; - VS::get_singleton()->canvas_light_set_item_mask(canvas_light,item_mask); + VS::get_singleton()->canvas_light_set_item_cull_mask(canvas_light,item_mask); } -int Light2D::get_item_mask() const { +int Light2D::get_item_cull_mask() const { return item_mask; } -void Light2D::set_item_shadow_mask( int p_mask) { +void Light2D::set_item_shadow_cull_mask( int p_mask) { item_shadow_mask=p_mask; - VS::get_singleton()->canvas_light_set_item_shadow_mask(canvas_light,item_shadow_mask); + VS::get_singleton()->canvas_light_set_item_shadow_cull_mask(canvas_light,item_shadow_mask); } -int Light2D::get_item_shadow_mask() const { +int Light2D::get_item_shadow_cull_mask() const { return item_shadow_mask; } @@ -292,17 +292,30 @@ int Light2D::get_shadow_buffer_size() const { return shadow_buffer_size; } -void Light2D::set_shadow_esm_multiplier( float p_multiplier) { +void Light2D::set_shadow_gradient_length( float p_multiplier) { - shadow_esm_multiplier=p_multiplier; - VS::get_singleton()->canvas_light_set_shadow_esm_multiplier(canvas_light,p_multiplier); + shadow_gradient_length=p_multiplier; + VS::get_singleton()->canvas_light_set_shadow_gradient_length(canvas_light,p_multiplier); } -float Light2D::get_shadow_esm_multiplier() const{ +float Light2D::get_shadow_gradient_length() const{ - return shadow_esm_multiplier; + return shadow_gradient_length; } + +void Light2D::set_shadow_filter( ShadowFilter p_filter) { + shadow_filter=p_filter; + VS::get_singleton()->canvas_light_set_shadow_filter(canvas_light,VS::CanvasLightShadowFilter(p_filter )); +} + +Light2D::ShadowFilter Light2D::get_shadow_filter() const { + + return shadow_filter; +} + + + void Light2D::set_shadow_color( const Color& p_shadow_color) { shadow_color=p_shadow_color; VS::get_singleton()->canvas_light_set_shadow_color(canvas_light,shadow_color); @@ -390,11 +403,11 @@ void Light2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_layer_range_max"),&Light2D::get_layer_range_max); - ObjectTypeDB::bind_method(_MD("set_item_mask","item_mask"),&Light2D::set_item_mask); - ObjectTypeDB::bind_method(_MD("get_item_mask"),&Light2D::get_item_mask); + ObjectTypeDB::bind_method(_MD("set_item_cull_mask","item_cull_mask"),&Light2D::set_item_cull_mask); + ObjectTypeDB::bind_method(_MD("get_item_cull_mask"),&Light2D::get_item_cull_mask); - ObjectTypeDB::bind_method(_MD("set_item_shadow_mask","item_shadow_mask"),&Light2D::set_item_shadow_mask); - ObjectTypeDB::bind_method(_MD("get_item_shadow_mask"),&Light2D::get_item_shadow_mask); + ObjectTypeDB::bind_method(_MD("set_item_shadow_cull_mask","item_shadow_cull_mask"),&Light2D::set_item_shadow_cull_mask); + ObjectTypeDB::bind_method(_MD("get_item_shadow_cull_mask"),&Light2D::get_item_shadow_cull_mask); ObjectTypeDB::bind_method(_MD("set_mode","mode"),&Light2D::set_mode); ObjectTypeDB::bind_method(_MD("get_mode"),&Light2D::get_mode); @@ -405,8 +418,11 @@ void Light2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_shadow_buffer_size","size"),&Light2D::set_shadow_buffer_size); ObjectTypeDB::bind_method(_MD("get_shadow_buffer_size"),&Light2D::get_shadow_buffer_size); - ObjectTypeDB::bind_method(_MD("set_shadow_esm_multiplier","multiplier"),&Light2D::set_shadow_esm_multiplier); - ObjectTypeDB::bind_method(_MD("get_shadow_esm_multiplier"),&Light2D::get_shadow_esm_multiplier); + ObjectTypeDB::bind_method(_MD("set_shadow_gradient_length","multiplier"),&Light2D::set_shadow_gradient_length); + ObjectTypeDB::bind_method(_MD("get_shadow_gradient_length"),&Light2D::get_shadow_gradient_length); + + ObjectTypeDB::bind_method(_MD("set_shadow_filter","filter"),&Light2D::set_shadow_filter); + ObjectTypeDB::bind_method(_MD("get_shadow_filter"),&Light2D::get_shadow_filter); ObjectTypeDB::bind_method(_MD("set_shadow_color","shadow_color"),&Light2D::set_shadow_color); ObjectTypeDB::bind_method(_MD("get_shadow_color"),&Light2D::get_shadow_color); @@ -425,12 +441,13 @@ void Light2D::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max")); ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_min",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_min"),_SCS("get_layer_range_min")); ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_max",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_max"),_SCS("get_layer_range_max")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"range/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/item_cull_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_cull_mask"),_SCS("get_item_cull_mask")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow/enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled")); ADD_PROPERTY( PropertyInfo(Variant::COLOR,"shadow/color"),_SCS("set_shadow_color"),_SCS("get_shadow_color")); ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/buffer_size",PROPERTY_HINT_RANGE,"32,16384,1"),_SCS("set_shadow_buffer_size"),_SCS("get_shadow_buffer_size")); - ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/esm_multiplier",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_esm_multiplier"),_SCS("get_shadow_esm_multiplier")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_shadow_mask"),_SCS("get_item_shadow_mask")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/gradient_length",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_gradient_length"),_SCS("get_shadow_gradient_length")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/filter",PROPERTY_HINT_ENUM,"None,PCF3,PCF5,PCF9,PCF13"),_SCS("set_shadow_filter"),_SCS("get_shadow_filter")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/item_cull_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_shadow_cull_mask"),_SCS("get_item_shadow_cull_mask")); BIND_CONSTANT( MODE_ADD ); BIND_CONSTANT( MODE_SUB ); @@ -457,9 +474,10 @@ Light2D::Light2D() { item_shadow_mask=1; mode=MODE_ADD; shadow_buffer_size=2048; - shadow_esm_multiplier=80; + shadow_gradient_length=0; energy=1.0; shadow_color=Color(0,0,0,0); + shadow_filter=SHADOW_FILTER_NONE; } diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 7bed137348..d3aaa0f1ed 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -42,6 +42,14 @@ public: MODE_MASK, }; + enum ShadowFilter { + SHADOW_FILTER_NONE, + SHADOW_FILTER_PCF3, + SHADOW_FILTER_PCF5, + SHADOW_FILTER_PCF9, + SHADOW_FILTER_PCF13, + }; + private: RID canvas_light; bool enabled; @@ -59,10 +67,12 @@ private: int item_mask; int item_shadow_mask; int shadow_buffer_size; - float shadow_esm_multiplier; + float shadow_gradient_length; Mode mode; Ref<Texture> texture; Vector2 texture_offset; + ShadowFilter shadow_filter; + void _update_light_visibility(); protected: @@ -112,11 +122,11 @@ public: void set_layer_range_max( int p_max_layer); int get_layer_range_max() const; - void set_item_mask( int p_mask); - int get_item_mask() const; + void set_item_cull_mask( int p_mask); + int get_item_cull_mask() const; - void set_item_shadow_mask( int p_mask); - int get_item_shadow_mask() const; + void set_item_shadow_cull_mask( int p_mask); + int get_item_shadow_cull_mask() const; void set_mode( Mode p_mode ); Mode get_mode() const; @@ -127,8 +137,11 @@ public: void set_shadow_buffer_size( int p_size ); int get_shadow_buffer_size() const; - void set_shadow_esm_multiplier( float p_multiplier); - float get_shadow_esm_multiplier() const; + void set_shadow_gradient_length( float p_multiplier); + float get_shadow_gradient_length() const; + + void set_shadow_filter( ShadowFilter p_filter); + ShadowFilter get_shadow_filter() const; void set_shadow_color( const Color& p_shadow_color); Color get_shadow_color() const; @@ -143,5 +156,7 @@ public: }; VARIANT_ENUM_CAST(Light2D::Mode); +VARIANT_ENUM_CAST(Light2D::ShadowFilter); + #endif // LIGHT_2D_H diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h index 47ed805bba..52e92cd5fe 100644 --- a/scene/2d/particles_2d.h +++ b/scene/2d/particles_2d.h @@ -117,7 +117,6 @@ private: float randomness[PARAM_MAX]; struct Particle { - bool active; Point2 pos; Vector2 velocity; diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index c885dddee8..51329ff996 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -377,7 +377,7 @@ Sprite::Sprite() { /// /// - +#if 0 void ViewportSprite::edit_set_pivot(const Point2& p_pivot) { set_offset(p_pivot); @@ -589,3 +589,4 @@ ViewportSprite::ViewportSprite() { centered=true; modulate=Color(1,1,1,1); } +#endif diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index d94fee66b3..ce8478ff40 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -107,6 +107,7 @@ public: Sprite(); }; +#if 0 class ViewportSprite : public Node2D { OBJ_TYPE( ViewportSprite, Node2D ); @@ -149,4 +150,5 @@ public: ViewportSprite(); }; +#endif #endif // SPRITE_H diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index ed16212f3e..c1116d4aaa 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -352,7 +352,6 @@ void TileMap::_update_dirty_quadrants() { xform.set_origin( q.pos ); vs->canvas_item_set_transform( canvas_item, xform ); vs->canvas_item_set_light_mask(canvas_item,get_light_mask()); - vs->canvas_item_set_blend_mode(canvas_item,VS::MaterialBlendMode(get_blend_mode())); q.canvas_items.push_back(canvas_item); @@ -478,7 +477,7 @@ void TileMap::_update_dirty_quadrants() { _fix_cell_transform(xform,c,shape_ofs+center_ofs,s); - if (debug_canvas_item) { + if (debug_canvas_item.is_valid()) { vs->canvas_item_add_set_transform(debug_canvas_item,xform); shape->draw(debug_canvas_item,debug_collision_color); @@ -489,7 +488,7 @@ void TileMap::_update_dirty_quadrants() { } } - if (debug_canvas_item) { + if (debug_canvas_item.is_valid()) { vs->canvas_item_add_set_transform(debug_canvas_item,Matrix32()); } @@ -542,26 +541,19 @@ void TileMap::_update_dirty_quadrants() { if (quadrant_order_dirty) { + int index=-0x80000000; //always must be drawn below children for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) { Quadrant &q=E->get(); for (List<RID>::Element *E=q.canvas_items.front();E;E=E->next()) { - VS::get_singleton()->canvas_item_raise(E->get()); + VS::get_singleton()->canvas_item_set_draw_index(E->get(),index++); } } quadrant_order_dirty=false; } - for(int i=0;i<get_child_count();i++) { - - CanvasItem *c=get_child(i)->cast_to<CanvasItem>(); - - if (c) - VS::get_singleton()->canvas_item_raise(c->get_canvas_item()); - } - _recompute_rect_cache(); } @@ -1191,14 +1183,6 @@ void TileMap::set_light_mask(int p_light_mask) { } } -void TileMap::set_blend_mode(BlendMode p_blend_mode) { - - CanvasItem::set_blend_mode(p_blend_mode); - _recreate_quadrants(); - -} - - void TileMap::_bind_methods() { diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 7ef4605527..c95d2cd048 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -255,8 +255,6 @@ public: void set_occluder_light_mask(int p_mask); int get_occluder_light_mask() const; - void set_blend_mode(BlendMode p_blend_mode); - virtual void set_light_mask(int p_light_mask); void clear(); diff --git a/scene/3d/baked_light_instance.cpp b/scene/3d/baked_light_instance.cpp index ed1984db26..051256deb4 100644 --- a/scene/3d/baked_light_instance.cpp +++ b/scene/3d/baked_light_instance.cpp @@ -28,82 +28,1737 @@ /*************************************************************************/ #include "baked_light_instance.h" #include "scene/scene_string_names.h" +#include "mesh_instance.h" +#include "light.h" +#include "math.h" +#define FINDMINMAX(x0,x1,x2,min,max) \ + min = max = x0; \ + if(x1<min) min=x1;\ + if(x1>max) max=x1;\ + if(x2<min) min=x2;\ + if(x2>max) max=x2; -RID BakedLightInstance::get_baked_light_instance() const { +static bool planeBoxOverlap(Vector3 normal,float d, Vector3 maxbox) +{ + int q; + Vector3 vmin,vmax; + for(q=0;q<=2;q++) + { + if(normal[q]>0.0f) + { + vmin[q]=-maxbox[q]; + vmax[q]=maxbox[q]; + } + else + { + vmin[q]=maxbox[q]; + vmax[q]=-maxbox[q]; + } + } + if(normal.dot(vmin)+d>0.0f) return false; + if(normal.dot(vmax)+d>=0.0f) return true; - if (baked_light.is_null()) - return RID(); - else - return get_instance(); + return false; +} + + +/*======================== X-tests ========================*/ +#define AXISTEST_X01(a, b, fa, fb) \ + p0 = a*v0.y - b*v0.z; \ + p2 = a*v2.y - b*v2.z; \ + if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ + rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ + if(min>rad || max<-rad) return false; + +#define AXISTEST_X2(a, b, fa, fb) \ + p0 = a*v0.y - b*v0.z; \ + p1 = a*v1.y - b*v1.z; \ + if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ + rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ + if(min>rad || max<-rad) return false; + +/*======================== Y-tests ========================*/ +#define AXISTEST_Y02(a, b, fa, fb) \ + p0 = -a*v0.x + b*v0.z; \ + p2 = -a*v2.x + b*v2.z; \ + if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ + if(min>rad || max<-rad) return false; + +#define AXISTEST_Y1(a, b, fa, fb) \ + p0 = -a*v0.x + b*v0.z; \ + p1 = -a*v1.x + b*v1.z; \ + if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ + if(min>rad || max<-rad) return false; + +/*======================== Z-tests ========================*/ + +#define AXISTEST_Z12(a, b, fa, fb) \ + p1 = a*v1.x - b*v1.y; \ + p2 = a*v2.x - b*v2.y; \ + if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;} \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ + if(min>rad || max<-rad) return false; + +#define AXISTEST_Z0(a, b, fa, fb) \ + p0 = a*v0.x - b*v0.y; \ + p1 = a*v1.x - b*v1.y; \ + if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ + if(min>rad || max<-rad) return false; + +static bool fast_tri_box_overlap(const Vector3& boxcenter,const Vector3 boxhalfsize,const Vector3 *triverts) { + + /* use separating axis theorem to test overlap between triangle and box */ + /* need to test for overlap in these directions: */ + /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ + /* we do not even need to test these) */ + /* 2) normal of the triangle */ + /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ + /* this gives 3x3=9 more tests */ + Vector3 v0,v1,v2; + float min,max,d,p0,p1,p2,rad,fex,fey,fez; + Vector3 normal,e0,e1,e2; + + /* This is the fastest branch on Sun */ + /* move everything so that the boxcenter is in (0,0,0) */ + + v0=triverts[0]-boxcenter; + v1=triverts[1]-boxcenter; + v2=triverts[2]-boxcenter; + + /* compute triangle edges */ + e0=v1-v0; /* tri edge 0 */ + e1=v2-v1; /* tri edge 1 */ + e2=v0-v2; /* tri edge 2 */ + + /* Bullet 3: */ + /* test the 9 tests first (this was faster) */ + fex = Math::abs(e0.x); + fey = Math::abs(e0.y); + fez = Math::abs(e0.z); + AXISTEST_X01(e0.z, e0.y, fez, fey); + AXISTEST_Y02(e0.z, e0.x, fez, fex); + AXISTEST_Z12(e0.y, e0.x, fey, fex); + + fex = Math::abs(e1.x); + fey = Math::abs(e1.y); + fez = Math::abs(e1.z); + AXISTEST_X01(e1.z, e1.y, fez, fey); + AXISTEST_Y02(e1.z, e1.x, fez, fex); + AXISTEST_Z0(e1.y, e1.x, fey, fex); + + fex = Math::abs(e2.x); + fey = Math::abs(e2.y); + fez = Math::abs(e2.z); + AXISTEST_X2(e2.z, e2.y, fez, fey); + AXISTEST_Y1(e2.z, e2.x, fez, fex); + AXISTEST_Z12(e2.y, e2.x, fey, fex); + + /* Bullet 1: */ + /* first test overlap in the {x,y,z}-directions */ + /* find min, max of the triangle each direction, and test for overlap in */ + /* that direction -- this is equivalent to testing a minimal AABB around */ + /* the triangle against the AABB */ + + /* test in X-direction */ + FINDMINMAX(v0.x,v1.x,v2.x,min,max); + if(min>boxhalfsize.x || max<-boxhalfsize.x) return false; + + /* test in Y-direction */ + FINDMINMAX(v0.y,v1.y,v2.y,min,max); + if(min>boxhalfsize.y || max<-boxhalfsize.y) return false; + + /* test in Z-direction */ + FINDMINMAX(v0.z,v1.z,v2.z,min,max); + if(min>boxhalfsize.z || max<-boxhalfsize.z) return false; + + /* Bullet 2: */ + /* test if the box intersects the plane of the triangle */ + /* compute plane equation of triangle: normal*x+d=0 */ + normal=e0.cross(e1); + d=-normal.dot(v0); /* plane eq: normal.x+d=0 */ + if(!planeBoxOverlap(normal,d,boxhalfsize)) return false; + + return true; /* box and triangle overlaps */ +} + + +Vector<Color> BakedLight::_get_bake_texture(Image &p_image,const Color& p_color) { + + Vector<Color> ret; + + if (p_image.empty()) { + + ret.resize(bake_texture_size*bake_texture_size); + for(int i=0;i<bake_texture_size*bake_texture_size;i++) { + ret[i]=p_color; + } + + return ret; + } + + p_image.convert(Image::FORMAT_RGBA8); + p_image.resize(bake_texture_size,bake_texture_size,Image::INTERPOLATE_CUBIC); + + + DVector<uint8_t>::Read r = p_image.get_data().read(); + ret.resize(bake_texture_size*bake_texture_size); + + for(int i=0;i<bake_texture_size*bake_texture_size;i++) { + Color c; + c.r = r[i*4+0]/255.0; + c.g = r[i*4+1]/255.0; + c.b = r[i*4+2]/255.0; + c.a = r[i*4+3]/255.0; + ret[i]=c; + + } + + return ret; +} + + +BakedLight::MaterialCache BakedLight::_get_material_cache(Ref<Material> p_material) { + + //this way of obtaining materials is inaccurate and also does not support some compressed formats very well + Ref<FixedSpatialMaterial> mat = p_material; + + Ref<Material> material = mat; //hack for now + + if (material_cache.has(material)) { + return material_cache[material]; + } + + MaterialCache mc; + + if (mat.is_valid()) { + + + Ref<ImageTexture> albedo_tex = mat->get_texture(FixedSpatialMaterial::TEXTURE_ALBEDO); + + Image img_albedo; + if (albedo_tex.is_valid()) { + + img_albedo = albedo_tex->get_data(); + } + + mc.albedo=_get_bake_texture(img_albedo,mat->get_albedo()); + + Ref<ImageTexture> emission_tex = mat->get_texture(FixedSpatialMaterial::TEXTURE_EMISSION); + + Color emission_col = mat->get_emission(); + emission_col.r*=mat->get_emission_energy(); + emission_col.g*=mat->get_emission_energy(); + emission_col.b*=mat->get_emission_energy(); + + Image img_emission; + + if (emission_tex.is_valid()) { + + img_emission = emission_tex->get_data(); + } + + mc.emission=_get_bake_texture(img_emission,emission_col); + + } else { + Image empty; + + mc.albedo=_get_bake_texture(empty,Color(0.7,0.7,0.7)); + mc.emission=_get_bake_texture(empty,Color(0,0,0)); + + + } + + material_cache[p_material]=mc; + return mc; + + +} + + + +static _FORCE_INLINE_ Vector2 get_uv(const Vector3& p_pos, const Vector3 *p_vtx, const Vector2* p_uv) { + + if (p_pos.distance_squared_to(p_vtx[0])<CMP_EPSILON2) + return p_uv[0]; + if (p_pos.distance_squared_to(p_vtx[1])<CMP_EPSILON2) + return p_uv[1]; + if (p_pos.distance_squared_to(p_vtx[2])<CMP_EPSILON2) + return p_uv[2]; + + Vector3 v0 = p_vtx[1] - p_vtx[0]; + Vector3 v1 = p_vtx[2] - p_vtx[0]; + Vector3 v2 = p_pos - p_vtx[0]; + + float d00 = v0.dot( v0); + float d01 = v0.dot( v1); + float d11 = v1.dot( v1); + float d20 = v2.dot( v0); + float d21 = v2.dot( v1); + float denom = (d00 * d11 - d01 * d01); + if (denom==0) + return p_uv[0]; + float v = (d11 * d20 - d01 * d21) / denom; + float w = (d00 * d21 - d01 * d20) / denom; + float u = 1.0f - v - w; + + return p_uv[0]*u + p_uv[1]*v + p_uv[2]*w; +} + +void BakedLight::_plot_face(int p_idx, int p_level, const Vector3 *p_vtx, const Vector2* p_uv, const MaterialCache& p_material, const AABB &p_aabb) { + + + + if (p_level==cell_subdiv-1) { + //plot the face by guessing it's albedo and emission value + + //find best axis to map to, for scanning values + int closest_axis; + float closest_dot; + + Vector3 normal = Plane(p_vtx[0],p_vtx[1],p_vtx[2]).normal; + + for(int i=0;i<3;i++) { + + Vector3 axis; + axis[i]=1.0; + float dot=ABS(normal.dot(axis)); + if (i==0 || dot>closest_dot) { + closest_axis=i; + closest_dot=dot; + } + } + + Vector3 axis; + axis[closest_axis]=1.0; + Vector3 t1; + t1[(closest_axis+1)%3]=1.0; + Vector3 t2; + t2[(closest_axis+2)%3]=1.0; + + t1*=p_aabb.size[(closest_axis+1)%3]/float(color_scan_cell_width); + t2*=p_aabb.size[(closest_axis+2)%3]/float(color_scan_cell_width); + + Color albedo_accum; + Color emission_accum; + float alpha=0.0; + + //map to a grid average in the best axis for this face + for(int i=0;i<color_scan_cell_width;i++) { + + Vector3 ofs_i=float(i)*t1; + + for(int j=0;j<color_scan_cell_width;j++) { + + Vector3 ofs_j=float(j)*t2; + + Vector3 from = p_aabb.pos+ofs_i+ofs_j; + Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis]; + Vector3 half = (to-from)*0.5; + + //is in this cell? + if (!fast_tri_box_overlap(from+half,half,p_vtx)) { + continue; //face does not span this cell + } + + //go from -size to +size*2 to avoid skipping collisions + Vector3 ray_from = from + (t1+t2)*0.5 - axis * p_aabb.size[closest_axis]; + Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis]*2; + + Vector3 intersection; + + if (!Geometry::ray_intersects_triangle(ray_from,ray_to,p_vtx[0],p_vtx[1],p_vtx[2],&intersection)) { + //no intersect? look in edges + + float closest_dist=1e20; + for(int j=0;j<3;j++) { + Vector3 c; + Vector3 inters; + Geometry::get_closest_points_between_segments(p_vtx[j],p_vtx[(j+1)%3],ray_from,ray_to,inters,c); + float d=c.distance_to(intersection); + if (j==0 || d<closest_dist) { + closest_dist=d; + intersection=inters; + } + } + } + + Vector2 uv = get_uv(intersection,p_vtx,p_uv); + + + int uv_x = CLAMP(Math::fposmod(uv.x,1.0)*bake_texture_size,0,bake_texture_size-1); + int uv_y = CLAMP(Math::fposmod(uv.y,1.0)*bake_texture_size,0,bake_texture_size-1); + + int ofs = uv_y*bake_texture_size+uv_x; + albedo_accum.r+=p_material.albedo[ofs].r; + albedo_accum.g+=p_material.albedo[ofs].g; + albedo_accum.b+=p_material.albedo[ofs].b; + albedo_accum.a+=p_material.albedo[ofs].a; + + emission_accum.r+=p_material.emission[ofs].r; + emission_accum.g+=p_material.emission[ofs].g; + emission_accum.b+=p_material.emission[ofs].b; + alpha+=1.0; + + } + } + + + if (alpha==0) { + //could not in any way get texture information.. so use closest point to center + + Face3 f( p_vtx[0],p_vtx[1],p_vtx[2]); + Vector3 inters = f.get_closest_point_to(p_aabb.pos+p_aabb.size*0.5); + + Vector2 uv = get_uv(inters,p_vtx,p_uv); + + int uv_x = CLAMP(Math::fposmod(uv.x,1.0)*bake_texture_size,0,bake_texture_size-1); + int uv_y = CLAMP(Math::fposmod(uv.y,1.0)*bake_texture_size,0,bake_texture_size-1); + + int ofs = uv_y*bake_texture_size+uv_x; + + alpha = 1.0/(color_scan_cell_width*color_scan_cell_width); + + albedo_accum.r=p_material.albedo[ofs].r*alpha; + albedo_accum.g=p_material.albedo[ofs].g*alpha; + albedo_accum.b=p_material.albedo[ofs].b*alpha; + albedo_accum.a=p_material.albedo[ofs].a*alpha; + + emission_accum.r=p_material.emission[ofs].r*alpha; + emission_accum.g=p_material.emission[ofs].g*alpha; + emission_accum.b=p_material.emission[ofs].b*alpha; + + + zero_alphas++; + } else { + + float accdiv = 1.0/(color_scan_cell_width*color_scan_cell_width); + alpha*=accdiv; + + albedo_accum.r*=accdiv; + albedo_accum.g*=accdiv; + albedo_accum.b*=accdiv; + albedo_accum.a*=accdiv; + + emission_accum.r*=accdiv; + emission_accum.g*=accdiv; + emission_accum.b*=accdiv; + } + + //put this temporarily here, corrected in a later step + bake_cells_write[p_idx].albedo[0]+=albedo_accum.r; + bake_cells_write[p_idx].albedo[1]+=albedo_accum.g; + bake_cells_write[p_idx].albedo[2]+=albedo_accum.b; + bake_cells_write[p_idx].light[0]+=emission_accum.r; + bake_cells_write[p_idx].light[1]+=emission_accum.g; + bake_cells_write[p_idx].light[2]+=emission_accum.b; + bake_cells_write[p_idx].alpha+=alpha; + + static const Vector3 side_normals[6]={ + Vector3(-1, 0, 0), + Vector3( 1, 0, 0), + Vector3( 0,-1, 0), + Vector3( 0, 1, 0), + Vector3( 0, 0,-1), + Vector3( 0, 0, 1), + }; + + for(int i=0;i<6;i++) { + if (normal.dot(side_normals[i])>CMP_EPSILON) { + bake_cells_write[p_idx].used_sides|=(1<<i); + } + } + + + } else { + //go down + for(int i=0;i<8;i++) { + + AABB aabb=p_aabb; + aabb.size*=0.5; + + if (i&1) + aabb.pos.x+=aabb.size.x; + if (i&2) + aabb.pos.y+=aabb.size.y; + if (i&4) + aabb.pos.z+=aabb.size.z; + + { + AABB test_aabb=aabb; + //test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time + Vector3 qsize = test_aabb.size*0.5; //quarter size, for fast aabb test + + if (!fast_tri_box_overlap(test_aabb.pos+qsize,qsize,p_vtx)) { + //if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) { + //does not fit in child, go on + continue; + } + + } + + if (bake_cells_write[p_idx].childs[i]==CHILD_EMPTY) { + //sub cell must be created + + if (bake_cells_used==(1<<bake_cells_alloc)) { + //exhausted cells, creating more space + bake_cells_alloc++; + bake_cells_write=DVector<BakeCell>::Write(); + bake_cells.resize(1<<bake_cells_alloc); + bake_cells_write=bake_cells.write(); + } + + bake_cells_write[p_idx].childs[i]=bake_cells_used; + bake_cells_level_used[p_level+1]++; + bake_cells_used++; + + + } + + + _plot_face(bake_cells_write[p_idx].childs[i],p_level+1,p_vtx,p_uv,p_material,aabb); + } + } +} + + + +void BakedLight::_fixup_plot(int p_idx, int p_level,int p_x,int p_y, int p_z) { + + + + if (p_level==cell_subdiv-1) { + + + float alpha = bake_cells_write[p_idx].alpha; + + bake_cells_write[p_idx].albedo[0]/=alpha; + bake_cells_write[p_idx].albedo[1]/=alpha; + bake_cells_write[p_idx].albedo[2]/=alpha; + + //transfer emission to light + bake_cells_write[p_idx].light[0]/=alpha; + bake_cells_write[p_idx].light[1]/=alpha; + bake_cells_write[p_idx].light[2]/=alpha; + + bake_cells_write[p_idx].alpha=1.0; + + //remove neighbours from used sides + + for(int n=0;n<6;n++) { + + int ofs[3]={0,0,0}; + + ofs[n/2]=(n&1)?1:-1; + + //convert to x,y,z on this level + int x=p_x; + int y=p_y; + int z=p_z; + + x+=ofs[0]; + y+=ofs[1]; + z+=ofs[2]; + + int ofs_x=0; + int ofs_y=0; + int ofs_z=0; + int size = 1<<p_level; + int half=size/2; + + + if (x<0 || x>=size || y<0 || y>=size || z<0 || z>=size) { + //neighbour is out, can't use it + bake_cells_write[p_idx].used_sides&=~(1<<uint32_t(n)); + continue; + } + + uint32_t neighbour=0; + + for(int i=0;i<cell_subdiv-1;i++) { + + BakeCell *bc = &bake_cells_write[neighbour]; + + int child = 0; + if (x >= ofs_x + half) { + child|=1; + ofs_x+=half; + } + if (y >= ofs_y + half) { + child|=2; + ofs_y+=half; + } + if (z >= ofs_z + half) { + child|=4; + ofs_z+=half; + } + + neighbour = bc->childs[child]; + if (neighbour==CHILD_EMPTY) { + break; + } + + half>>=1; + } + + if (neighbour!=CHILD_EMPTY) { + bake_cells_write[p_idx].used_sides&=~(1<<uint32_t(n)); + } + } + } else { + + + //go down + + float alpha_average=0; + int half = cells_per_axis >> (p_level+1); + for(int i=0;i<8;i++) { + + uint32_t child = bake_cells_write[p_idx].childs[i]; + + if (child==CHILD_EMPTY) + continue; + + + int nx=p_x; + int ny=p_y; + int nz=p_z; + + if (i&1) + nx+=half; + if (i&2) + ny+=half; + if (i&4) + nz+=half; + + _fixup_plot(child,p_level+1,nx,ny,nz); + alpha_average+=bake_cells_write[child].alpha; + } + + bake_cells_write[p_idx].alpha=alpha_average/8.0; + bake_cells_write[p_idx].light[0]=0; + bake_cells_write[p_idx].light[1]=0; + bake_cells_write[p_idx].light[2]=0; + bake_cells_write[p_idx].albedo[0]=0; + bake_cells_write[p_idx].albedo[1]=0; + bake_cells_write[p_idx].albedo[2]=0; + + } + + //clean up light + bake_cells_write[p_idx].light_pass=0; + //find neighbours + + + +} + + +void BakedLight::_bake_add_mesh(const Transform& p_xform,Ref<Mesh>& p_mesh) { + + + for(int i=0;i<p_mesh->get_surface_count();i++) { + + if (p_mesh->surface_get_primitive_type(i)!=Mesh::PRIMITIVE_TRIANGLES) + continue; //only triangles + + MaterialCache material = _get_material_cache(p_mesh->surface_get_material(i)); + + Array a = p_mesh->surface_get_arrays(i); + + + DVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; + DVector<Vector3>::Read vr=vertices.read(); + DVector<Vector2> uv = a[Mesh::ARRAY_TEX_UV]; + DVector<Vector2>::Read uvr; + DVector<int> index = a[Mesh::ARRAY_INDEX]; + + bool read_uv=false; + + if (uv.size()) { + + uvr=uv.read(); + read_uv=true; + } + + if (index.size()) { + + int facecount = index.size()/3; + DVector<int>::Read ir=index.read(); + + for(int j=0;j<facecount;j++) { + + Vector3 vtxs[3]; + Vector2 uvs[3]; + + for(int k=0;k<3;k++) { + vtxs[k]=p_xform.xform(vr[ir[j*3+k]]); + } + + if (read_uv) { + for(int k=0;k<3;k++) { + uvs[k]=uvr[ir[j*3+k]]; + } + } + + //plot face + _plot_face(0,0,vtxs,uvs,material,bounds); + } + + + + } else { + + int facecount = vertices.size()/3; + + for(int j=0;j<facecount;j++) { + + Vector3 vtxs[3]; + Vector2 uvs[3]; + + for(int k=0;k<3;k++) { + vtxs[k]=p_xform.xform(vr[j*3+k]); + } + + if (read_uv) { + for(int k=0;k<3;k++) { + uvs[k]=uvr[j*3+k]; + } + } + + //plot face + _plot_face(0,0,vtxs,uvs,material,bounds); + } + + } + } +} + + + +void BakedLight::_bake_add_to_aabb(const Transform& p_xform,Ref<Mesh>& p_mesh,bool &first) { + + for(int i=0;i<p_mesh->get_surface_count();i++) { + + if (p_mesh->surface_get_primitive_type(i)!=Mesh::PRIMITIVE_TRIANGLES) + continue; //only triangles + + Array a = p_mesh->surface_get_arrays(i); + DVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; + int vc = vertices.size(); + DVector<Vector3>::Read vr=vertices.read(); + + if (first) { + bounds.pos=p_xform.xform(vr[0]); + first=false; + } + + + for(int j=0;j<vc;j++) { + bounds.expand_to(p_xform.xform(vr[j])); + } + } +} + +void BakedLight::bake() { + + + bake_cells_alloc=16; + bake_cells.resize(1<<bake_cells_alloc); + bake_cells_used=1; + cells_per_axis=(1<<(cell_subdiv-1)); + zero_alphas=0; + + bool aabb_first=true; + print_line("Generating AABB"); + + bake_cells_level_used.resize(cell_subdiv); + for(int i=0;i<cell_subdiv;i++) { + bake_cells_level_used[i]=0; + } + + int count=0; + for (Set<GeometryInstance*>::Element *E=geometries.front();E;E=E->next()) { + + print_line("aabb geom "+itos(count)+"/"+itos(geometries.size())); + + GeometryInstance *geom = E->get(); + + if (geom->cast_to<MeshInstance>()) { + + MeshInstance *mesh_instance = geom->cast_to<MeshInstance>(); + Ref<Mesh> mesh = mesh_instance->get_mesh(); + if (mesh.is_valid()) { + + _bake_add_to_aabb(geom->get_relative_transform(this),mesh,aabb_first); + } + } + count++; + } + + print_line("AABB: "+bounds); + ERR_FAIL_COND(aabb_first); + + bake_cells_write = bake_cells.write(); + count=0; + + for (Set<GeometryInstance*>::Element *E=geometries.front();E;E=E->next()) { + + GeometryInstance *geom = E->get(); + print_line("plot geom "+itos(count)+"/"+itos(geometries.size())); + + if (geom->cast_to<MeshInstance>()) { + + MeshInstance *mesh_instance = geom->cast_to<MeshInstance>(); + Ref<Mesh> mesh = mesh_instance->get_mesh(); + if (mesh.is_valid()) { + + _bake_add_mesh(geom->get_relative_transform(this),mesh); + } + } + + count++; + } + + + _fixup_plot(0, 0,0,0,0); + + + bake_cells_write=DVector<BakeCell>::Write(); + + bake_cells.resize(bake_cells_used); + + + + print_line("total bake cells used: "+itos(bake_cells_used)); + for(int i=0;i<cell_subdiv;i++) { + print_line("level "+itos(i)+": "+itos(bake_cells_level_used[i])); + } + print_line("zero alphas: "+itos(zero_alphas)); + + + +} + + + +void BakedLight::_bake_directional(int p_idx, int p_level, int p_x,int p_y,int p_z,const Vector3& p_dir,const Color& p_color,int p_sign) { + + + + + if (p_level==cell_subdiv-1) { + + Vector3 end; + end.x = float(p_x+0.5) / cells_per_axis; + end.y = float(p_y+0.5) / cells_per_axis; + end.z = float(p_z+0.5) / cells_per_axis; + + end = bounds.pos + bounds.size*end; + + float max_ray_len = (bounds.size).length()*1.2; + Vector3 begin = end + max_ray_len*-p_dir; + + //clip begin + + for(int i=0;i<3;i++) { + + if (ABS(p_dir[i])<CMP_EPSILON) { + continue; // parallel to axis, don't clip + } + + Plane p; + p.normal[i]=1.0; + p.d=bounds.pos[i]; + if (p_dir[i]<0) { + p.d+=bounds.size[i]; + } + + Vector3 inters; + if (p.intersects_segment(end,begin,&inters)) { + begin=inters; + } + + } + + + int idx = _plot_ray(begin,end); + + if (idx>=0 && light_pass!=bake_cells_write[idx].light_pass) { + //hit something, add or remove light to it + + Color albedo = Color(bake_cells_write[idx].albedo[0],bake_cells_write[idx].albedo[1],bake_cells_write[idx].albedo[2]); + bake_cells_write[idx].light[0]+=albedo.r*p_color.r*p_sign; + bake_cells_write[idx].light[1]+=albedo.g*p_color.g*p_sign; + bake_cells_write[idx].light[2]+=albedo.b*p_color.b*p_sign; + bake_cells_write[idx].light_pass=light_pass; + + } + + + } else { + + int half = cells_per_axis >> (p_level+1); + + //go down + for(int i=0;i<8;i++) { + + uint32_t child = bake_cells_write[p_idx].childs[i]; + + if (child==CHILD_EMPTY) + continue; + + int nx=p_x; + int ny=p_y; + int nz=p_z; + + if (i&1) + nx+=half; + if (i&2) + ny+=half; + if (i&4) + nz+=half; + + + _bake_directional(child,p_level+1,nx,ny,nz,p_dir,p_color,p_sign); + } + } +} + + + + +void BakedLight::_bake_light(Light* p_light) { + + if (p_light->cast_to<DirectionalLight>()) { + + DirectionalLight * dl = p_light->cast_to<DirectionalLight>(); + + Transform rel_xf = dl->get_relative_transform(this); + + Vector3 light_dir = -rel_xf.basis.get_axis(2); + + Color color = dl->get_color(); + float nrg = dl->get_param(Light::PARAM_ENERGY);; + color.r*=nrg; + color.g*=nrg; + color.b*=nrg; + + light_pass++; + _bake_directional(0,0,0,0,0,light_dir,color,1); + + } +} + + +void BakedLight::_upscale_light(int p_idx,int p_level) { + + + //go down + + float light_accum[3]={0,0,0}; + float alpha_accum=0; + + bool check_children = p_level < (cell_subdiv -2); + + for(int i=0;i<8;i++) { + + uint32_t child = bake_cells_write[p_idx].childs[i]; + + if (child==CHILD_EMPTY) + continue; + + if (check_children) { + _upscale_light(child,p_level+1); + } + + light_accum[0]+=bake_cells_write[child].light[0]; + light_accum[1]+=bake_cells_write[child].light[1]; + light_accum[2]+=bake_cells_write[child].light[2]; + alpha_accum+=bake_cells_write[child].alpha; + + } + + bake_cells_write[p_idx].light[0]=light_accum[0]/8.0; + bake_cells_write[p_idx].light[1]=light_accum[1]/8.0; + bake_cells_write[p_idx].light[2]=light_accum[2]/8.0; + bake_cells_write[p_idx].alpha=alpha_accum/8.0; + +} + + +void BakedLight::bake_lights() { + + ERR_FAIL_COND(bake_cells.size()==0); + + bake_cells_write = bake_cells.write(); + + for(Set<Light*>::Element *E=lights.front();E;E=E->next()) { + + _bake_light(E->get()); + } + + + _upscale_light(0,0); + + bake_cells_write=DVector<BakeCell>::Write(); + +} + + + +Color BakedLight::_cone_trace(const Vector3& p_from, const Vector3& p_dir, float p_half_angle) { + + + Color color(0,0,0,0); + float tha = Math::tan(p_half_angle);//tan half angle + Vector3 from =(p_from-bounds.pos)/bounds.size; //convert to 0..1 + from/=cells_per_axis; //convert to voxels of size 1 + Vector3 dir = (p_dir/bounds.size).normalized(); + + float max_dist = Vector3(cells_per_axis,cells_per_axis,cells_per_axis).length(); + + float dist = 1.0; + // self occlusion in flat surfaces + + float alpha=0; + + + while(dist < max_dist && alpha < 0.95) { + +#if 0 + // smallest sample diameter possible is the voxel size + float diameter = MAX(1.0, 2.0 * tha * dist); + float lod = log2(diameter); + + Vector3 sample_pos = from + dist * dir; + + + Color samples_base[2][8]={{Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0)}, + {Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0)}}; + + float levelf = Math::fposmod(lod,1.0); + float fx = Math::fposmod(sample_pos.x,1.0); + float fy = Math::fposmod(sample_pos.y,1.0); + float fz = Math::fposmod(sample_pos.z,1.0); + + for(int l=0;l<2;l++){ + + int bx = Math::floor(sample_pos.x); + int by = Math::floor(sample_pos.y); + int bz = Math::floor(sample_pos.z); + + int lodn=int(Math::floor(lod))-l; + + bx>>=lodn; + by>>=lodn; + bz>>=lodn; + + int limit = MAX(0,cell_subdiv-lodn-1); + + for(int c=0;c<8;c++) { + + int x = bx; + int y = by; + int z = bz; + + if (c&1) { + x+=1; + } + if (c&2) { + y+=1; + } + if (c&4) { + z+=1; + } + + int ofs_x=0; + int ofs_y=0; + int ofs_z=0; + int size = cells_per_axis>>lodn; + int half=size/2; + + bool outside=x<0 || x>=size || y<0 || y>=size || z<0 || z>=size; + + if (outside) + continue; + + + uint32_t cell=0; + + for(int i=0;i<limit;i++) { + + BakeCell *bc = &bake_cells_write[cell]; + + int child = 0; + if (x >= ofs_x + half) { + child|=1; + ofs_x+=half; + } + if (y >= ofs_y + half) { + child|=2; + ofs_y+=half; + } + if (z >= ofs_z + half) { + child|=4; + ofs_z+=half; + } + + cell = bc->childs[child]; + if (cell==CHILD_EMPTY) + break; + + half>>=1; + } + + if (cell!=CHILD_EMPTY) { + + samples_base[l][c].r=bake_cells_write[cell].light[0]; + samples_base[l][c].g=bake_cells_write[cell].light[1]; + samples_base[l][c].b=bake_cells_write[cell].light[2]; + samples_base[l][c].a=bake_cells_write[cell].alpha; + } + + } + + + } + + Color m0x0 = samples_base[0][0].linear_interpolate(samples_base[0][1],fx); + Color m0x1 = samples_base[0][2].linear_interpolate(samples_base[0][3],fx); + Color m0y0 = m0x0.linear_interpolate(m0x1,fy); + m0x0 = samples_base[0][4].linear_interpolate(samples_base[0][5],fx); + m0x1 = samples_base[0][6].linear_interpolate(samples_base[0][7],fx); + Color m0y1 = m0x0.linear_interpolate(m0x1,fy); + Color m0z = m0y0.linear_interpolate(m0y1,fz); + + Color m1x0 = samples_base[1][0].linear_interpolate(samples_base[1][1],fx); + Color m1x1 = samples_base[1][2].linear_interpolate(samples_base[1][3],fx); + Color m1y0 = m1x0.linear_interpolate(m1x1,fy); + m1x0 = samples_base[1][4].linear_interpolate(samples_base[1][5],fx); + m1x1 = samples_base[1][6].linear_interpolate(samples_base[1][7],fx); + Color m1y1 = m1x0.linear_interpolate(m1x1,fy); + Color m1z = m1y0.linear_interpolate(m1y1,fz); + + Color m = m0z.linear_interpolate(m1z,levelf); +#else + float diameter = 1.0; + Vector3 sample_pos = from + dist * dir; + + Color m(0,0,0,0); + { + int x = Math::floor(sample_pos.x); + int y = Math::floor(sample_pos.y); + int z = Math::floor(sample_pos.z); + + int ofs_x=0; + int ofs_y=0; + int ofs_z=0; + int size = cells_per_axis; + int half=size/2; + + bool outside=x<0 || x>=size || y<0 || y>=size || z<0 || z>=size; + + if (!outside) { + + + uint32_t cell=0; + + for(int i=0;i<cell_subdiv-1;i++) { + + BakeCell *bc = &bake_cells_write[cell]; + + int child = 0; + if (x >= ofs_x + half) { + child|=1; + ofs_x+=half; + } + if (y >= ofs_y + half) { + child|=2; + ofs_y+=half; + } + if (z >= ofs_z + half) { + child|=4; + ofs_z+=half; + } + + cell = bc->childs[child]; + if (cell==CHILD_EMPTY) + break; + + half>>=1; + } + + if (cell!=CHILD_EMPTY) { + + m.r=bake_cells_write[cell].light[0]; + m.g=bake_cells_write[cell].light[1]; + m.b=bake_cells_write[cell].light[2]; + m.a=bake_cells_write[cell].alpha; + } + } + } + +#endif + // front-to-back compositing + float a = (1.0 - alpha); + color.r += a * m.r; + color.g += a * m.g; + color.b += a * m.b; + alpha += a * m.a; + //occlusion += a * voxelColor.a; + //occlusion += (a * voxelColor.a) / (1.0 + 0.03 * diameter); + dist += diameter * 0.5; // smoother + //dist += diameter; // faster but misses more voxels + } + + return color; +} + + + +void BakedLight::_bake_radiance(int p_idx, int p_level, int p_x,int p_y,int p_z) { + + + + + if (p_level==cell_subdiv-1) { + + const int NUM_CONES = 6; + Vector3 cone_directions[6] = { + Vector3(1, 0, 0), + Vector3(0.5, 0.866025, 0), + Vector3( 0.5, 0.267617, 0.823639), + Vector3( 0.5, -0.700629, 0.509037), + Vector3( 0.5, -0.700629, -0.509037), + Vector3( 0.5, 0.267617, -0.823639) + }; + float coneWeights[6] = {0.25, 0.15, 0.15, 0.15, 0.15, 0.15}; + + Vector3 pos = (Vector3(p_x,p_y,p_z)/float(cells_per_axis))*bounds.size+bounds.pos; + Vector3 voxel_size = bounds.size/float(cells_per_axis); + pos+=voxel_size*0.5; + + Color accum; + + bake_cells_write[p_idx].light[0]=0; + bake_cells_write[p_idx].light[1]=0; + bake_cells_write[p_idx].light[2]=0; + + int freepix=0; + for(int i=0;i<6;i++) { + + if (!(bake_cells_write[p_idx].used_sides&(1<<i))) + continue; + + if ((i&1)==0) + bake_cells_write[p_idx].light[i/2]=1.0; + freepix++; + continue; + + int ofs = i/2; + + Vector3 dir; + if ((i&1)==0) + dir[ofs]=1.0; + else + dir[ofs]=-1.0; + + for(int j=0;j<1;j++) { + + + Vector3 cone_dir; + cone_dir.x = cone_directions[j][(ofs+0)%3]; + cone_dir.y = cone_directions[j][(ofs+1)%3]; + cone_dir.z = cone_directions[j][(ofs+2)%3]; + + cone_dir[ofs]*=dir[ofs]; + + Color res = _cone_trace(pos+dir*voxel_size,cone_dir,Math::deg2rad(29.9849)); + accum.r+=res.r;//*coneWeights[j]; + accum.g+=res.g;//*coneWeights[j]; + accum.b+=res.b;//*coneWeights[j]; + } + + + } +#if 0 + if (freepix==0) { + bake_cells_write[p_idx].light[0]=0; + bake_cells_write[p_idx].light[1]=0; + bake_cells_write[p_idx].light[2]=0; + } + + if (freepix==1) { + bake_cells_write[p_idx].light[0]=1; + bake_cells_write[p_idx].light[1]=0; + bake_cells_write[p_idx].light[2]=0; + } + + if (freepix==2) { + bake_cells_write[p_idx].light[0]=0; + bake_cells_write[p_idx].light[1]=1; + bake_cells_write[p_idx].light[2]=0; + } + + if (freepix==3) { + bake_cells_write[p_idx].light[0]=1; + bake_cells_write[p_idx].light[1]=1; + bake_cells_write[p_idx].light[2]=0; + } + + if (freepix==4) { + bake_cells_write[p_idx].light[0]=0; + bake_cells_write[p_idx].light[1]=0; + bake_cells_write[p_idx].light[2]=1; + } + + if (freepix==5) { + bake_cells_write[p_idx].light[0]=1; + bake_cells_write[p_idx].light[1]=0; + bake_cells_write[p_idx].light[2]=1; + } + + if (freepix==6) { + bake_cells_write[p_idx].light[0]=0; + bake_cells_write[p_idx].light[0]=1; + bake_cells_write[p_idx].light[0]=1; + } +#endif + //bake_cells_write[p_idx].radiance[0]=accum.r; + //bake_cells_write[p_idx].radiance[1]=accum.g; + //bake_cells_write[p_idx].radiance[2]=accum.b; + + + } else { + + int half = cells_per_axis >> (p_level+1); + + //go down + for(int i=0;i<8;i++) { + + uint32_t child = bake_cells_write[p_idx].childs[i]; + + if (child==CHILD_EMPTY) + continue; + + int nx=p_x; + int ny=p_y; + int nz=p_z; + + if (i&1) + nx+=half; + if (i&2) + ny+=half; + if (i&4) + nz+=half; + + + _bake_radiance(child,p_level+1,nx,ny,nz); + } + } } -void BakedLightInstance::set_baked_light(const Ref<BakedLight>& p_baked_light) { +void BakedLight::bake_radiance() { + + ERR_FAIL_COND(bake_cells.size()==0); - baked_light=p_baked_light; + bake_cells_write = bake_cells.write(); + + _bake_radiance(0,0,0,0,0); + + bake_cells_write=DVector<BakeCell>::Write(); + +} +int BakedLight::_find_cell(int x,int y, int z) { - RID base_rid; - if (baked_light.is_valid()) - base_rid=baked_light->get_rid(); - else - base_rid=RID(); + uint32_t cell=0; - set_base(base_rid); + int ofs_x=0; + int ofs_y=0; + int ofs_z=0; + int size = cells_per_axis; + int half=size/2; - if (is_inside_world()) { + if (x<0 || x>=size) + return -1; + if (y<0 || y>=size) + return -1; + if (z<0 || z>=size) + return -1; - emit_signal(SceneStringNames::get_singleton()->baked_light_changed); + for(int i=0;i<cell_subdiv-1;i++) { -// for (List<Node*>::Element *E=baked_geometry.front();E;E=E->next()) { -// VS::get_singleton()->instance_geometry_set_baked_light(E->get()->get_instance(),baked_light.is_valid()?get_instance():RID()); -// } + BakeCell *bc = &bake_cells_write[cell]; + + int child = 0; + if (x >= ofs_x + half) { + child|=1; + ofs_x+=half; + } + if (y >= ofs_y + half) { + child|=2; + ofs_y+=half; + } + if (z >= ofs_z + half) { + child|=4; + ofs_z+=half; + } + + cell = bc->childs[child]; + if (cell==CHILD_EMPTY) + return -1; + + half>>=1; } - update_configuration_warning(); + return cell; + } -Ref<BakedLight> BakedLightInstance::get_baked_light() const{ - return baked_light; +int BakedLight::_plot_ray(const Vector3& p_from, const Vector3& p_to) { + + Vector3 from = (p_from - bounds.pos) / bounds.size; + Vector3 to = (p_to - bounds.pos) / bounds.size; + + int x1 = Math::floor(from.x*cells_per_axis); + int y1 = Math::floor(from.y*cells_per_axis); + int z1 = Math::floor(from.z*cells_per_axis); + + int x2 = Math::floor(to.x*cells_per_axis); + int y2 = Math::floor(to.y*cells_per_axis); + int z2 = Math::floor(to.z*cells_per_axis); + + + int i, dx, dy, dz, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2; + int point[3]; + + point[0] = x1; + point[1] = y1; + point[2] = z1; + dx = x2 - x1; + dy = y2 - y1; + dz = z2 - z1; + x_inc = (dx < 0) ? -1 : 1; + l = ABS(dx); + y_inc = (dy < 0) ? -1 : 1; + m = ABS(dy); + z_inc = (dz < 0) ? -1 : 1; + n = ABS(dz); + dx2 = l << 1; + dy2 = m << 1; + dz2 = n << 1; + + if ((l >= m) && (l >= n)) { + err_1 = dy2 - l; + err_2 = dz2 - l; + for (i = 0; i < l; i++) { + int cell = _find_cell(point[0],point[1],point[2]); + if (cell>=0) + return cell; + + if (err_1 > 0) { + point[1] += y_inc; + err_1 -= dx2; + } + if (err_2 > 0) { + point[2] += z_inc; + err_2 -= dx2; + } + err_1 += dy2; + err_2 += dz2; + point[0] += x_inc; + } + } else if ((m >= l) && (m >= n)) { + err_1 = dx2 - m; + err_2 = dz2 - m; + for (i = 0; i < m; i++) { + int cell = _find_cell(point[0],point[1],point[2]); + if (cell>=0) + return cell; + if (err_1 > 0) { + point[0] += x_inc; + err_1 -= dy2; + } + if (err_2 > 0) { + point[2] += z_inc; + err_2 -= dy2; + } + err_1 += dx2; + err_2 += dz2; + point[1] += y_inc; + } + } else { + err_1 = dy2 - n; + err_2 = dx2 - n; + for (i = 0; i < n; i++) { + int cell = _find_cell(point[0],point[1],point[2]); + if (cell>=0) + return cell; + + if (err_1 > 0) { + point[1] += y_inc; + err_1 -= dz2; + } + if (err_2 > 0) { + point[0] += x_inc; + err_2 -= dz2; + } + err_1 += dy2; + err_2 += dx2; + point[2] += z_inc; + } + } + return _find_cell(point[0],point[1],point[2]); + } -AABB BakedLightInstance::get_aabb() const { + +void BakedLight::set_cell_subdiv(int p_subdiv) { + + cell_subdiv=p_subdiv; + +// VS::get_singleton()->baked_light_set_subdivision(baked_light,p_subdiv); +} + +int BakedLight::get_cell_subdiv() const { + + return cell_subdiv; +} + + + +AABB BakedLight::get_aabb() const { return AABB(Vector3(0,0,0),Vector3(1,1,1)); } -DVector<Face3> BakedLightInstance::get_faces(uint32_t p_usage_flags) const { +DVector<Face3> BakedLight::get_faces(uint32_t p_usage_flags) const { return DVector<Face3>(); } -String BakedLightInstance::get_configuration_warning() const { - if (get_baked_light().is_null()) { - return TTR("BakedLightInstance does not contain a BakedLight resource."); - } +String BakedLight::get_configuration_warning() const { return String(); } -void BakedLightInstance::_bind_methods() { +void BakedLight::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb,DebugMode p_mode,Ref<MultiMesh> &p_multimesh,int &idx) { + + + if (p_level==cell_subdiv-1) { + + Vector3 center = p_aabb.pos+p_aabb.size*0.5; + Transform xform; + xform.origin=center; + xform.basis.scale(p_aabb.size*0.5); + p_multimesh->set_instance_transform(idx,xform); + Color col; + switch(p_mode) { + case DEBUG_ALBEDO: { + col=Color(bake_cells_write[p_idx].albedo[0],bake_cells_write[p_idx].albedo[1],bake_cells_write[p_idx].albedo[2]); + } break; + case DEBUG_LIGHT: { + col=Color(bake_cells_write[p_idx].light[0],bake_cells_write[p_idx].light[1],bake_cells_write[p_idx].light[2]); + Color colr=Color(bake_cells_write[p_idx].radiance[0],bake_cells_write[p_idx].radiance[1],bake_cells_write[p_idx].radiance[2]); + col.r+=colr.r; + col.g+=colr.g; + col.b+=colr.b; + } break; + + } + p_multimesh->set_instance_color(idx,col); + + + idx++; + + } else { - ObjectTypeDB::bind_method(_MD("set_baked_light","baked_light"),&BakedLightInstance::set_baked_light); - ObjectTypeDB::bind_method(_MD("get_baked_light"),&BakedLightInstance::get_baked_light); - ObjectTypeDB::bind_method(_MD("get_baked_light_instance"),&BakedLightInstance::get_baked_light_instance); + for(int i=0;i<8;i++) { - ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"baked_light",PROPERTY_HINT_RESOURCE_TYPE,"BakedLight"),_SCS("set_baked_light"),_SCS("get_baked_light")); + if (bake_cells_write[p_idx].childs[i]==CHILD_EMPTY) + continue; + + AABB aabb=p_aabb; + aabb.size*=0.5; + + if (i&1) + aabb.pos.x+=aabb.size.x; + if (i&2) + aabb.pos.y+=aabb.size.y; + if (i&4) + aabb.pos.z+=aabb.size.z; + + _debug_mesh(bake_cells_write[p_idx].childs[i],p_level+1,aabb,p_mode,p_multimesh,idx); + } + + } + +} + + +void BakedLight::create_debug_mesh(DebugMode p_mode) { + + Ref<MultiMesh> mm; + mm.instance(); + + mm->set_transform_format(MultiMesh::TRANSFORM_3D); + mm->set_color_format(MultiMesh::COLOR_8BIT); + mm->set_instance_count(bake_cells_level_used[cell_subdiv-1]); + + Ref<Mesh> mesh; + mesh.instance(); + + + + { + Array arr; + arr.resize(Mesh::ARRAY_MAX); + + DVector<Vector3> vertices; + DVector<Color> colors; + + int vtx_idx=0; + #define ADD_VTX(m_idx);\ + vertices.push_back( face_points[m_idx] );\ + colors.push_back( Color(1,1,1,1) );\ + vtx_idx++;\ + + for (int i=0;i<6;i++) { + + + Vector3 face_points[4]; + + for (int j=0;j<4;j++) { + + float v[3]; + v[0]=1.0; + v[1]=1-2*((j>>1)&1); + v[2]=v[1]*(1-2*(j&1)); + + for (int k=0;k<3;k++) { + + if (i<3) + face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1); + else + face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); + } + } + + //tri 1 + ADD_VTX(0); + ADD_VTX(1); + ADD_VTX(2); + //tri 2 + ADD_VTX(2); + ADD_VTX(3); + ADD_VTX(0); + + } + + + arr[Mesh::ARRAY_VERTEX]=vertices; + arr[Mesh::ARRAY_COLOR]=colors; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES,arr); + } + + { + Ref<FixedSpatialMaterial> fsm; + fsm.instance(); + fsm->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR,true); + fsm->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true); + fsm->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true); + fsm->set_albedo(Color(1,1,1,1)); + + mesh->surface_set_material(0,fsm); + } + + mm->set_mesh(mesh); + + + bake_cells_write = bake_cells.write(); + + + + int idx=0; + _debug_mesh(0,0,bounds,p_mode,mm,idx); + + print_line("written: "+itos(idx)+" total: "+itos(bake_cells_level_used[cell_subdiv-1])); + + + MultiMeshInstance *mmi = memnew( MultiMeshInstance ); + mmi->set_multimesh(mm); + add_child(mmi); + if (get_tree()->get_edited_scene_root()==this){ + mmi->set_owner(this); + } else { + mmi->set_owner(get_owner()); + + } + +} + +void BakedLight::_debug_mesh_albedo() { + create_debug_mesh(DEBUG_ALBEDO); +} + +void BakedLight::_debug_mesh_light() { + create_debug_mesh(DEBUG_LIGHT); +} + + +void BakedLight::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_cell_subdiv","steps"),&BakedLight::set_cell_subdiv); + ObjectTypeDB::bind_method(_MD("get_cell_subdiv"),&BakedLight::get_cell_subdiv); + + ObjectTypeDB::bind_method(_MD("bake"),&BakedLight::bake); + ObjectTypeDB::set_method_flags(get_type_static(),_SCS("bake"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); + + ObjectTypeDB::bind_method(_MD("bake_lights"),&BakedLight::bake_lights); + ObjectTypeDB::set_method_flags(get_type_static(),_SCS("bake_lights"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); + + ObjectTypeDB::bind_method(_MD("bake_radiance"),&BakedLight::bake_radiance); + ObjectTypeDB::set_method_flags(get_type_static(),_SCS("bake_radiance"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); + + ObjectTypeDB::bind_method(_MD("debug_mesh_albedo"),&BakedLight::_debug_mesh_albedo); + ObjectTypeDB::set_method_flags(get_type_static(),_SCS("debug_mesh_albedo"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); + + + ObjectTypeDB::bind_method(_MD("debug_mesh_light"),&BakedLight::_debug_mesh_light); + ObjectTypeDB::set_method_flags(get_type_static(),_SCS("debug_mesh_light"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); + + ADD_PROPERTY(PropertyInfo(Variant::INT,"cell_subdiv"),_SCS("set_cell_subdiv"),_SCS("get_cell_subdiv")); ADD_SIGNAL( MethodInfo("baked_light_changed")); + } -BakedLightInstance::BakedLightInstance() { +BakedLight::BakedLight() { +// baked_light=VisualServer::get_singleton()->baked_light_create(); + VS::get_singleton()->instance_set_base(get_instance(),baked_light); + cell_subdiv=8; + bake_texture_size=128; + color_scan_cell_width=8; + light_pass=0; } -///////////////////////// +BakedLight::~BakedLight() { + + VS::get_singleton()->free(baked_light); +} + +///////////////////////// + +#if 0 void BakedLightSampler::set_param(Param p_param,float p_value) { ERR_FAIL_INDEX(p_param,PARAM_MAX); params[p_param]=p_value; @@ -179,3 +1834,4 @@ BakedLightSampler::~BakedLightSampler(){ VS::get_singleton()->free(base); } +#endif diff --git a/scene/3d/baked_light_instance.h b/scene/3d/baked_light_instance.h index a31b0b0dab..4913eae908 100644 --- a/scene/3d/baked_light_instance.h +++ b/scene/3d/baked_light_instance.h @@ -31,37 +31,142 @@ #include "scene/3d/visual_instance.h" #include "scene/resources/baked_light.h" +#include "scene/3d/multimesh_instance.h" + class BakedLightBaker; +class Light; + +class BakedLight : public VisualInstance { + OBJ_TYPE(BakedLight,VisualInstance); + +public: + enum DebugMode { + DEBUG_ALBEDO, + DEBUG_LIGHT + }; + +private: + RID baked_light; + int cell_subdiv; + AABB bounds; + int cells_per_axis; + + enum { + CHILD_EMPTY=0xFFFFFFFF, + }; + + + /* BAKE DATA */ + + struct BakeCell { + + uint32_t childs[8]; + float albedo[3]; //albedo in RGB24 + float light[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast) + float radiance[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast) + uint32_t used_sides; + float alpha; //used for upsampling + uint32_t light_pass; //used for baking light + + BakeCell() { + for(int i=0;i<8;i++) { + childs[i]=0xFFFFFFFF; + } + + for(int i=0;i<3;i++) { + light[i]=0; + albedo[i]=0; + radiance[i]=0; + } + alpha=0; + light_pass=0; + used_sides=0; + } + }; + + + int bake_texture_size; + int color_scan_cell_width; + + struct MaterialCache { + //128x128 textures + Vector<Color> albedo; + Vector<Color> emission; + }; + + Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color); -class BakedLightInstance : public VisualInstance { - OBJ_TYPE(BakedLightInstance,VisualInstance); - Ref<BakedLight> baked_light; + Map<Ref<Material>,MaterialCache> material_cache; + MaterialCache _get_material_cache(Ref<Material> p_material); + int bake_cells_alloc; + int bake_cells_used; + int zero_alphas; + Vector<int> bake_cells_level_used; + DVector<BakeCell> bake_cells; + DVector<BakeCell>::Write bake_cells_write; + + + + void _plot_face(int p_idx,int p_level,const Vector3 *p_vtx,const Vector2* p_uv, const MaterialCache& p_material,const AABB& p_aabb); + void _fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z); + void _bake_add_mesh(const Transform& p_xform,Ref<Mesh>& p_mesh); + void _bake_add_to_aabb(const Transform& p_xform,Ref<Mesh>& p_mesh,bool &first); + + void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb,DebugMode p_mode,Ref<MultiMesh> &p_multimesh,int &idx); + void _debug_mesh_albedo(); + void _debug_mesh_light(); + + + _FORCE_INLINE_ int _find_cell(int x,int y, int z); + int _plot_ray(const Vector3& p_from, const Vector3& p_to); + + uint32_t light_pass; + + + void _bake_directional(int p_idx, int p_level, int p_x,int p_y,int p_z,const Vector3& p_dir,const Color& p_color,int p_sign); + void _upscale_light(int p_idx,int p_level); + void _bake_light(Light* p_light); + + Color _cone_trace(const Vector3& p_from, const Vector3& p_dir, float p_half_angle); + void _bake_radiance(int p_idx, int p_level, int p_x,int p_y,int p_z); + +friend class GeometryInstance; + + Set<GeometryInstance*> geometries; +friend class Light; + + Set<Light*> lights; protected: static void _bind_methods(); public: + void set_cell_subdiv(int p_subdiv); + int get_cell_subdiv() const; + + void bake(); + void bake_lights(); + void bake_radiance(); - RID get_baked_light_instance() const; - void set_baked_light(const Ref<BakedLight>& baked_light); - Ref<BakedLight> get_baked_light() const; + void create_debug_mesh(DebugMode p_mode); virtual AABB get_aabb() const; virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const; String get_configuration_warning() const; - BakedLightInstance(); + BakedLight(); + ~BakedLight(); }; - +#if 0 class BakedLightSampler : public VisualInstance { OBJ_TYPE(BakedLightSampler,VisualInstance); @@ -101,5 +206,5 @@ public: VARIANT_ENUM_CAST( BakedLightSampler::Param ); - +#endif #endif // BAKED_LIGHT_H diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 56e16ee309..a9a5ea7371 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -96,8 +96,8 @@ bool Camera::_set(const StringName& p_name, const Variant& p_value) { } else { clear_current(); } - } else if (p_name=="visible_layers") { - set_visible_layers(p_value); + } else if (p_name=="cull_mask") { + set_cull_mask(p_value); } else if (p_name=="environment") { set_environment(p_value); } else @@ -130,8 +130,8 @@ bool Camera::_get(const StringName& p_name,Variant &r_ret) const { } else { r_ret=is_current(); } - } else if (p_name=="visible_layers") { - r_ret=get_visible_layers(); + } else if (p_name=="cull_mask") { + r_ret=get_cull_mask(); } else if (p_name=="h_offset") { r_ret=get_h_offset(); } else if (p_name=="v_offset") { @@ -176,7 +176,7 @@ void Camera::_get_property_list( List<PropertyInfo> *p_list) const { p_list->push_back( PropertyInfo( Variant::REAL, "far" , PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01") ); p_list->push_back( PropertyInfo( Variant::INT, "keep_aspect",PROPERTY_HINT_ENUM,"Keep Width,Keep Height") ); p_list->push_back( PropertyInfo( Variant::BOOL, "current" ) ); - p_list->push_back( PropertyInfo( Variant::INT, "visible_layers",PROPERTY_HINT_ALL_FLAGS ) ); + p_list->push_back( PropertyInfo( Variant::INT, "cull_mask",PROPERTY_HINT_ALL_FLAGS ) ); p_list->push_back( PropertyInfo( Variant::OBJECT, "environment",PROPERTY_HINT_RESOURCE_TYPE,"Environment" ) ); p_list->push_back( PropertyInfo( Variant::REAL, "h_offset" ) ); p_list->push_back( PropertyInfo( Variant::REAL, "v_offset" ) ); @@ -342,91 +342,6 @@ bool Camera::_can_gizmo_scale() const { } -RES Camera::_get_gizmo_geometry() const { - - - Ref<SurfaceTool> surface_tool( memnew( SurfaceTool )); - - Ref<FixedMaterial> mat( memnew( FixedMaterial )); - - mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.5,1.0,0.5) ); - mat->set_line_width(4); - mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); - mat->set_flag(Material::FLAG_UNSHADED,true); - //mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); - - surface_tool->begin(Mesh::PRIMITIVE_LINES); - surface_tool->set_material(mat); - - switch(mode) { - - case PROJECTION_PERSPECTIVE: { - - - - Vector3 side=Vector3( Math::sin(Math::deg2rad(fov)), 0, -Math::cos(Math::deg2rad(fov)) ); - Vector3 nside=side; - nside.x=-nside.x; - Vector3 up=Vector3(0,side.x,0); - - -#define ADD_TRIANGLE( m_a, m_b, m_c)\ -{\ - surface_tool->add_vertex(m_a);\ - surface_tool->add_vertex(m_b);\ - surface_tool->add_vertex(m_b);\ - surface_tool->add_vertex(m_c);\ - surface_tool->add_vertex(m_c);\ - surface_tool->add_vertex(m_a);\ -} - - ADD_TRIANGLE( Vector3(), side+up, side-up ); - ADD_TRIANGLE( Vector3(), nside+up, nside-up ); - ADD_TRIANGLE( Vector3(), side+up, nside+up ); - ADD_TRIANGLE( Vector3(), side-up, nside-up ); - - side.x*=0.25; - nside.x*=0.25; - Vector3 tup( 0, up.y*3/2,side.z); - ADD_TRIANGLE( tup, side+up, nside+up ); - - } break; - case PROJECTION_ORTHOGONAL: { - -#define ADD_QUAD( m_a, m_b, m_c, m_d)\ -{\ - surface_tool->add_vertex(m_a);\ - surface_tool->add_vertex(m_b);\ - surface_tool->add_vertex(m_b);\ - surface_tool->add_vertex(m_c);\ - surface_tool->add_vertex(m_c);\ - surface_tool->add_vertex(m_d);\ - surface_tool->add_vertex(m_d);\ - surface_tool->add_vertex(m_a);\ -} - - float hsize=size*0.5; - Vector3 right(hsize,0,0); - Vector3 up(0,hsize,0); - Vector3 back(0,0,-1.0); - Vector3 front(0,0,0); - - ADD_QUAD( -up-right,-up+right,up+right,up-right); - ADD_QUAD( -up-right+back,-up+right+back,up+right+back,up-right+back); - ADD_QUAD( up+right,up+right+back,up-right+back,up-right); - ADD_QUAD( -up+right,-up+right+back,-up-right+back,-up-right); - - right.x*=0.25; - Vector3 tup( 0, up.y*3/2,back.z ); - ADD_TRIANGLE( tup, right+up+back, -right+up+back ); - - } break; - - } - - return surface_tool->commit(); - -} Vector3 Camera::project_ray_normal(const Point2& p_pos) const { @@ -652,8 +567,8 @@ void Camera::_bind_methods() { ObjectTypeDB::bind_method( _MD("get_h_offset"),&Camera::get_h_offset ); ObjectTypeDB::bind_method( _MD("set_v_offset","ofs"),&Camera::set_v_offset ); ObjectTypeDB::bind_method( _MD("get_v_offset"),&Camera::get_v_offset ); - ObjectTypeDB::bind_method( _MD("set_visible_layers","mask"),&Camera::set_visible_layers ); - ObjectTypeDB::bind_method( _MD("get_visible_layers"),&Camera::get_visible_layers ); + ObjectTypeDB::bind_method( _MD("set_cull_mask","mask"),&Camera::set_cull_mask ); + ObjectTypeDB::bind_method( _MD("get_cull_mask"),&Camera::get_cull_mask ); ObjectTypeDB::bind_method( _MD("set_environment","env:Environment"),&Camera::set_environment ); ObjectTypeDB::bind_method( _MD("get_environment:Environment"),&Camera::get_environment ); ObjectTypeDB::bind_method( _MD("set_keep_aspect_mode","mode"),&Camera::set_keep_aspect_mode ); @@ -694,13 +609,13 @@ Camera::Projection Camera::get_projection() const { return mode; } -void Camera::set_visible_layers(uint32_t p_layers) { +void Camera::set_cull_mask(uint32_t p_layers) { layers=p_layers; - VisualServer::get_singleton()->camera_set_visible_layers(camera,layers); + VisualServer::get_singleton()->camera_set_cull_mask(camera,layers); } -uint32_t Camera::get_visible_layers() const{ +uint32_t Camera::get_cull_mask() const{ return layers; } @@ -761,7 +676,7 @@ Camera::Camera() { layers=0xfffff; v_offset=0; h_offset=0; - VisualServer::get_singleton()->camera_set_visible_layers(camera,layers); + VisualServer::get_singleton()->camera_set_cull_mask(camera,layers); //active=false; } diff --git a/scene/3d/camera.h b/scene/3d/camera.h index 554990997e..409cc29401 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -75,7 +75,7 @@ private: Ref<Environment> environment; virtual bool _can_gizmo_scale() const; - virtual RES _get_gizmo_geometry() const; + //void _camera_make_current(Node *p_camera); @@ -126,8 +126,8 @@ public: bool is_position_behind(const Vector3& p_pos) const; Vector3 project_position(const Point2& p_point) const; - void set_visible_layers(uint32_t p_layers); - uint32_t get_visible_layers() const; + void set_cull_mask(uint32_t p_layers); + uint32_t get_cull_mask() const; Vector<Plane> get_frustum() const; diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp new file mode 100644 index 0000000000..f8d8213b82 --- /dev/null +++ b/scene/3d/gi_probe.cpp @@ -0,0 +1,1403 @@ +#include "gi_probe.h" +#include "mesh_instance.h" + + +void GIProbeData::set_bounds(const AABB& p_bounds) { + + VS::get_singleton()->gi_probe_set_bounds(probe,p_bounds); +} + +AABB GIProbeData::get_bounds() const{ + + return VS::get_singleton()->gi_probe_get_bounds(probe); +} + +void GIProbeData::set_cell_size(float p_size) { + + VS::get_singleton()->gi_probe_set_cell_size(probe,p_size); + +} + +float GIProbeData::get_cell_size() const { + + return VS::get_singleton()->gi_probe_get_cell_size(probe); + +} + +void GIProbeData::set_to_cell_xform(const Transform& p_xform) { + + VS::get_singleton()->gi_probe_set_to_cell_xform(probe,p_xform); + +} + +Transform GIProbeData::get_to_cell_xform() const { + + return VS::get_singleton()->gi_probe_get_to_cell_xform(probe); + +} + + +void GIProbeData::set_dynamic_data(const DVector<int>& p_data){ + + VS::get_singleton()->gi_probe_set_dynamic_data(probe,p_data); + +} +DVector<int> GIProbeData::get_dynamic_data() const{ + + return VS::get_singleton()->gi_probe_get_dynamic_data(probe); +} + +void GIProbeData::set_dynamic_range(int p_range){ + + VS::get_singleton()->gi_probe_set_dynamic_range(probe,p_range); + +} + +void GIProbeData::set_energy(float p_range) { + + VS::get_singleton()->gi_probe_set_energy(probe,p_range); +} + +float GIProbeData::get_energy() const{ + + return VS::get_singleton()->gi_probe_get_energy(probe); + +} + +void GIProbeData::set_interior(bool p_enable) { + + VS::get_singleton()->gi_probe_set_interior(probe,p_enable); + +} + +bool GIProbeData::is_interior() const{ + + return VS::get_singleton()->gi_probe_is_interior(probe); +} + + +bool GIProbeData::is_compressed() const{ + + return VS::get_singleton()->gi_probe_is_compressed(probe); +} + + +void GIProbeData::set_compress(bool p_enable) { + + VS::get_singleton()->gi_probe_set_compress(probe,p_enable); + +} + +int GIProbeData::get_dynamic_range() const{ + + + return VS::get_singleton()->gi_probe_get_dynamic_range(probe); +} + + +RID GIProbeData::get_rid() const { + + return probe; +} + + +void GIProbeData::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_bounds","bounds"),&GIProbeData::set_bounds); + ObjectTypeDB::bind_method(_MD("get_bounds"),&GIProbeData::get_bounds); + + ObjectTypeDB::bind_method(_MD("set_cell_size","cell_size"),&GIProbeData::set_cell_size); + ObjectTypeDB::bind_method(_MD("get_cell_size"),&GIProbeData::get_cell_size); + + ObjectTypeDB::bind_method(_MD("set_to_cell_xform","to_cell_xform"),&GIProbeData::set_to_cell_xform); + ObjectTypeDB::bind_method(_MD("get_to_cell_xform"),&GIProbeData::get_to_cell_xform); + + ObjectTypeDB::bind_method(_MD("set_dynamic_data","dynamic_data"),&GIProbeData::set_dynamic_data); + ObjectTypeDB::bind_method(_MD("get_dynamic_data"),&GIProbeData::get_dynamic_data); + + ObjectTypeDB::bind_method(_MD("set_dynamic_range","dynamic_range"),&GIProbeData::set_dynamic_range); + ObjectTypeDB::bind_method(_MD("get_dynamic_range"),&GIProbeData::get_dynamic_range); + + ObjectTypeDB::bind_method(_MD("set_energy","energy"),&GIProbeData::set_energy); + ObjectTypeDB::bind_method(_MD("get_energy"),&GIProbeData::get_energy); + + ObjectTypeDB::bind_method(_MD("set_interior","interior"),&GIProbeData::set_interior); + ObjectTypeDB::bind_method(_MD("is_interior"),&GIProbeData::is_interior); + + ObjectTypeDB::bind_method(_MD("set_compress","compress"),&GIProbeData::set_compress); + ObjectTypeDB::bind_method(_MD("is_compressed"),&GIProbeData::is_compressed); + + ADD_PROPERTY(PropertyInfo(Variant::_AABB,"bounds",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_bounds"),_SCS("get_bounds")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"cell_size",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_cell_size"),_SCS("get_cell_size")); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM,"to_cell_xform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_to_cell_xform"),_SCS("get_to_cell_xform")); + + ADD_PROPERTY(PropertyInfo(Variant::INT_ARRAY,"dynamic_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_dynamic_data"),_SCS("get_dynamic_data")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"dynamic_range",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_dynamic_range"),_SCS("get_dynamic_range")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"energy",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_energy"),_SCS("get_energy")); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"interior",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_interior"),_SCS("is_interior")); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"compress",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_compress"),_SCS("is_compressed")); + +} + +GIProbeData::GIProbeData() { + + probe=VS::get_singleton()->gi_probe_create(); +} + +GIProbeData::~GIProbeData() { + + VS::get_singleton()->free(probe); +} + + +////////////////////// +////////////////////// + + +void GIProbe::set_probe_data(const Ref<GIProbeData>& p_data) { + + if (p_data.is_valid()) { + VS::get_singleton()->instance_set_base(get_instance(),p_data->get_rid()); + } else { + VS::get_singleton()->instance_set_base(get_instance(),RID()); + } + + probe_data=p_data; +} + +Ref<GIProbeData> GIProbe::get_probe_data() const { + + return probe_data; +} + +void GIProbe::set_subdiv(Subdiv p_subdiv) { + + ERR_FAIL_INDEX(p_subdiv,SUBDIV_MAX); + subdiv=p_subdiv; + update_gizmo(); +} + +GIProbe::Subdiv GIProbe::get_subdiv() const { + + return subdiv; +} + +void GIProbe::set_extents(const Vector3& p_extents) { + + extents=p_extents; + update_gizmo(); +} + +Vector3 GIProbe::get_extents() const { + + return extents; +} + +void GIProbe::set_dynamic_range(int p_dynamic_range) { + + dynamic_range=p_dynamic_range; +} +int GIProbe::get_dynamic_range() const { + + return dynamic_range; +} + +void GIProbe::set_energy(float p_energy) { + + energy=p_energy; + if (probe_data.is_valid()) { + probe_data->set_energy(energy); + } +} +float GIProbe::get_energy() const { + + return energy; +} + +void GIProbe::set_interior(bool p_enable) { + + interior=p_enable; + if (probe_data.is_valid()) { + probe_data->set_interior(p_enable); + } +} + +bool GIProbe::is_interior() const { + + return interior; +} + + +void GIProbe::set_compress(bool p_enable) { + + compress=p_enable; + if (probe_data.is_valid()) { + probe_data->set_compress(p_enable); + } +} + +bool GIProbe::is_compressed() const { + + return compress; +} + + +#include "math.h" + +#define FINDMINMAX(x0,x1,x2,min,max) \ + min = max = x0; \ + if(x1<min) min=x1;\ + if(x1>max) max=x1;\ + if(x2<min) min=x2;\ + if(x2>max) max=x2; + +static bool planeBoxOverlap(Vector3 normal,float d, Vector3 maxbox) +{ + int q; + Vector3 vmin,vmax; + for(q=0;q<=2;q++) + { + if(normal[q]>0.0f) + { + vmin[q]=-maxbox[q]; + vmax[q]=maxbox[q]; + } + else + { + vmin[q]=maxbox[q]; + vmax[q]=-maxbox[q]; + } + } + if(normal.dot(vmin)+d>0.0f) return false; + if(normal.dot(vmax)+d>=0.0f) return true; + + return false; +} + + +/*======================== X-tests ========================*/ +#define AXISTEST_X01(a, b, fa, fb) \ + p0 = a*v0.y - b*v0.z; \ + p2 = a*v2.y - b*v2.z; \ + if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ + rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ + if(min>rad || max<-rad) return false; + +#define AXISTEST_X2(a, b, fa, fb) \ + p0 = a*v0.y - b*v0.z; \ + p1 = a*v1.y - b*v1.z; \ + if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ + rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ + if(min>rad || max<-rad) return false; + +/*======================== Y-tests ========================*/ +#define AXISTEST_Y02(a, b, fa, fb) \ + p0 = -a*v0.x + b*v0.z; \ + p2 = -a*v2.x + b*v2.z; \ + if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ + if(min>rad || max<-rad) return false; + +#define AXISTEST_Y1(a, b, fa, fb) \ + p0 = -a*v0.x + b*v0.z; \ + p1 = -a*v1.x + b*v1.z; \ + if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ + if(min>rad || max<-rad) return false; + +/*======================== Z-tests ========================*/ + +#define AXISTEST_Z12(a, b, fa, fb) \ + p1 = a*v1.x - b*v1.y; \ + p2 = a*v2.x - b*v2.y; \ + if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;} \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ + if(min>rad || max<-rad) return false; + +#define AXISTEST_Z0(a, b, fa, fb) \ + p0 = a*v0.x - b*v0.y; \ + p1 = a*v1.x - b*v1.y; \ + if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ + if(min>rad || max<-rad) return false; + +static bool fast_tri_box_overlap(const Vector3& boxcenter,const Vector3 boxhalfsize,const Vector3 *triverts) { + + /* use separating axis theorem to test overlap between triangle and box */ + /* need to test for overlap in these directions: */ + /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ + /* we do not even need to test these) */ + /* 2) normal of the triangle */ + /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ + /* this gives 3x3=9 more tests */ + Vector3 v0,v1,v2; + float min,max,d,p0,p1,p2,rad,fex,fey,fez; + Vector3 normal,e0,e1,e2; + + /* This is the fastest branch on Sun */ + /* move everything so that the boxcenter is in (0,0,0) */ + + v0=triverts[0]-boxcenter; + v1=triverts[1]-boxcenter; + v2=triverts[2]-boxcenter; + + /* compute triangle edges */ + e0=v1-v0; /* tri edge 0 */ + e1=v2-v1; /* tri edge 1 */ + e2=v0-v2; /* tri edge 2 */ + + /* Bullet 3: */ + /* test the 9 tests first (this was faster) */ + fex = Math::abs(e0.x); + fey = Math::abs(e0.y); + fez = Math::abs(e0.z); + AXISTEST_X01(e0.z, e0.y, fez, fey); + AXISTEST_Y02(e0.z, e0.x, fez, fex); + AXISTEST_Z12(e0.y, e0.x, fey, fex); + + fex = Math::abs(e1.x); + fey = Math::abs(e1.y); + fez = Math::abs(e1.z); + AXISTEST_X01(e1.z, e1.y, fez, fey); + AXISTEST_Y02(e1.z, e1.x, fez, fex); + AXISTEST_Z0(e1.y, e1.x, fey, fex); + + fex = Math::abs(e2.x); + fey = Math::abs(e2.y); + fez = Math::abs(e2.z); + AXISTEST_X2(e2.z, e2.y, fez, fey); + AXISTEST_Y1(e2.z, e2.x, fez, fex); + AXISTEST_Z12(e2.y, e2.x, fey, fex); + + /* Bullet 1: */ + /* first test overlap in the {x,y,z}-directions */ + /* find min, max of the triangle each direction, and test for overlap in */ + /* that direction -- this is equivalent to testing a minimal AABB around */ + /* the triangle against the AABB */ + + /* test in X-direction */ + FINDMINMAX(v0.x,v1.x,v2.x,min,max); + if(min>boxhalfsize.x || max<-boxhalfsize.x) return false; + + /* test in Y-direction */ + FINDMINMAX(v0.y,v1.y,v2.y,min,max); + if(min>boxhalfsize.y || max<-boxhalfsize.y) return false; + + /* test in Z-direction */ + FINDMINMAX(v0.z,v1.z,v2.z,min,max); + if(min>boxhalfsize.z || max<-boxhalfsize.z) return false; + + /* Bullet 2: */ + /* test if the box intersects the plane of the triangle */ + /* compute plane equation of triangle: normal*x+d=0 */ + normal=e0.cross(e1); + d=-normal.dot(v0); /* plane eq: normal.x+d=0 */ + if(!planeBoxOverlap(normal,d,boxhalfsize)) return false; + + return true; /* box and triangle overlaps */ +} + + + +static _FORCE_INLINE_ Vector2 get_uv(const Vector3& p_pos, const Vector3 *p_vtx, const Vector2* p_uv) { + + if (p_pos.distance_squared_to(p_vtx[0])<CMP_EPSILON2) + return p_uv[0]; + if (p_pos.distance_squared_to(p_vtx[1])<CMP_EPSILON2) + return p_uv[1]; + if (p_pos.distance_squared_to(p_vtx[2])<CMP_EPSILON2) + return p_uv[2]; + + Vector3 v0 = p_vtx[1] - p_vtx[0]; + Vector3 v1 = p_vtx[2] - p_vtx[0]; + Vector3 v2 = p_pos - p_vtx[0]; + + float d00 = v0.dot( v0); + float d01 = v0.dot( v1); + float d11 = v1.dot( v1); + float d20 = v2.dot( v0); + float d21 = v2.dot( v1); + float denom = (d00 * d11 - d01 * d01); + if (denom==0) + return p_uv[0]; + float v = (d11 * d20 - d01 * d21) / denom; + float w = (d00 * d21 - d01 * d20) / denom; + float u = 1.0f - v - w; + + return p_uv[0]*u + p_uv[1]*v + p_uv[2]*w; +} + +void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const Vector3 *p_vtx, const Vector2* p_uv, const Baker::MaterialCache& p_material, const AABB &p_aabb,Baker *p_baker) { + + + + if (p_level==p_baker->cell_subdiv-1) { + //plot the face by guessing it's albedo and emission value + + //find best axis to map to, for scanning values + int closest_axis; + float closest_dot; + + Vector3 normal = Plane(p_vtx[0],p_vtx[1],p_vtx[2]).normal; + + for(int i=0;i<3;i++) { + + Vector3 axis; + axis[i]=1.0; + float dot=ABS(normal.dot(axis)); + if (i==0 || dot>closest_dot) { + closest_axis=i; + closest_dot=dot; + } + } + + Vector3 axis; + axis[closest_axis]=1.0; + Vector3 t1; + t1[(closest_axis+1)%3]=1.0; + Vector3 t2; + t2[(closest_axis+2)%3]=1.0; + + t1*=p_aabb.size[(closest_axis+1)%3]/float(color_scan_cell_width); + t2*=p_aabb.size[(closest_axis+2)%3]/float(color_scan_cell_width); + + Color albedo_accum; + Color emission_accum; + Vector3 normal_accum; + + float alpha=0.0; + + //map to a grid average in the best axis for this face + for(int i=0;i<color_scan_cell_width;i++) { + + Vector3 ofs_i=float(i)*t1; + + for(int j=0;j<color_scan_cell_width;j++) { + + Vector3 ofs_j=float(j)*t2; + + Vector3 from = p_aabb.pos+ofs_i+ofs_j; + Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis]; + Vector3 half = (to-from)*0.5; + + //is in this cell? + if (!fast_tri_box_overlap(from+half,half,p_vtx)) { + continue; //face does not span this cell + } + + //go from -size to +size*2 to avoid skipping collisions + Vector3 ray_from = from + (t1+t2)*0.5 - axis * p_aabb.size[closest_axis]; + Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis]*2; + + Vector3 intersection; + + if (!Geometry::ray_intersects_triangle(ray_from,ray_to,p_vtx[0],p_vtx[1],p_vtx[2],&intersection)) { + //no intersect? look in edges + + float closest_dist=1e20; + for(int j=0;j<3;j++) { + Vector3 c; + Vector3 inters; + Geometry::get_closest_points_between_segments(p_vtx[j],p_vtx[(j+1)%3],ray_from,ray_to,inters,c); + float d=c.distance_to(intersection); + if (j==0 || d<closest_dist) { + closest_dist=d; + intersection=inters; + } + } + } + + Vector2 uv = get_uv(intersection,p_vtx,p_uv); + + + int uv_x = CLAMP(Math::fposmod(uv.x,1.0)*bake_texture_size,0,bake_texture_size-1); + int uv_y = CLAMP(Math::fposmod(uv.y,1.0)*bake_texture_size,0,bake_texture_size-1); + + int ofs = uv_y*bake_texture_size+uv_x; + albedo_accum.r+=p_material.albedo[ofs].r; + albedo_accum.g+=p_material.albedo[ofs].g; + albedo_accum.b+=p_material.albedo[ofs].b; + albedo_accum.a+=p_material.albedo[ofs].a; + + emission_accum.r+=p_material.emission[ofs].r; + emission_accum.g+=p_material.emission[ofs].g; + emission_accum.b+=p_material.emission[ofs].b; + + normal_accum+=normal; + + alpha+=1.0; + + } + } + + + if (alpha==0) { + //could not in any way get texture information.. so use closest point to center + + Face3 f( p_vtx[0],p_vtx[1],p_vtx[2]); + Vector3 inters = f.get_closest_point_to(p_aabb.pos+p_aabb.size*0.5); + + Vector2 uv = get_uv(inters,p_vtx,p_uv); + + int uv_x = CLAMP(Math::fposmod(uv.x,1.0)*bake_texture_size,0,bake_texture_size-1); + int uv_y = CLAMP(Math::fposmod(uv.y,1.0)*bake_texture_size,0,bake_texture_size-1); + + int ofs = uv_y*bake_texture_size+uv_x; + + alpha = 1.0/(color_scan_cell_width*color_scan_cell_width); + + albedo_accum.r=p_material.albedo[ofs].r*alpha; + albedo_accum.g=p_material.albedo[ofs].g*alpha; + albedo_accum.b=p_material.albedo[ofs].b*alpha; + albedo_accum.a=p_material.albedo[ofs].a*alpha; + + emission_accum.r=p_material.emission[ofs].r*alpha; + emission_accum.g=p_material.emission[ofs].g*alpha; + emission_accum.b=p_material.emission[ofs].b*alpha; + + normal_accum*=alpha; + + + } else { + + float accdiv = 1.0/(color_scan_cell_width*color_scan_cell_width); + alpha*=accdiv; + + albedo_accum.r*=accdiv; + albedo_accum.g*=accdiv; + albedo_accum.b*=accdiv; + albedo_accum.a*=accdiv; + + emission_accum.r*=accdiv; + emission_accum.g*=accdiv; + emission_accum.b*=accdiv; + + normal_accum*=accdiv; + + } + + //put this temporarily here, corrected in a later step + p_baker->bake_cells[p_idx].albedo[0]+=albedo_accum.r; + p_baker->bake_cells[p_idx].albedo[1]+=albedo_accum.g; + p_baker->bake_cells[p_idx].albedo[2]+=albedo_accum.b; + p_baker->bake_cells[p_idx].emission[0]+=emission_accum.r; + p_baker->bake_cells[p_idx].emission[1]+=emission_accum.g; + p_baker->bake_cells[p_idx].emission[2]+=emission_accum.b; + p_baker->bake_cells[p_idx].normal[0]+=normal_accum.x; + p_baker->bake_cells[p_idx].normal[1]+=normal_accum.y; + p_baker->bake_cells[p_idx].normal[2]+=normal_accum.z; + p_baker->bake_cells[p_idx].alpha+=alpha; + + static const Vector3 side_normals[6]={ + Vector3(-1, 0, 0), + Vector3( 1, 0, 0), + Vector3( 0,-1, 0), + Vector3( 0, 1, 0), + Vector3( 0, 0,-1), + Vector3( 0, 0, 1), + }; + + /* + for(int i=0;i<6;i++) { + if (normal.dot(side_normals[i])>CMP_EPSILON) { + p_baker->bake_cells[p_idx].used_sides|=(1<<i); + } + }*/ + + + } else { + //go down + + int half = (1<<(p_baker->cell_subdiv-1)) >> (p_level+1); + for(int i=0;i<8;i++) { + + AABB aabb=p_aabb; + aabb.size*=0.5; + + int nx=p_x; + int ny=p_y; + int nz=p_z; + + if (i&1) { + aabb.pos.x+=aabb.size.x; + nx+=half; + } + if (i&2) { + aabb.pos.y+=aabb.size.y; + ny+=half; + } + if (i&4) { + aabb.pos.z+=aabb.size.z; + nz+=half; + } + //make sure to not plot beyond limits + if (nx<0 || nx>=p_baker->axis_cell_size[0] || ny<0 || ny>=p_baker->axis_cell_size[1] || nz<0 || nz>=p_baker->axis_cell_size[2]) + continue; + + { + AABB test_aabb=aabb; + //test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time + Vector3 qsize = test_aabb.size*0.5; //quarter size, for fast aabb test + + if (!fast_tri_box_overlap(test_aabb.pos+qsize,qsize,p_vtx)) { + //if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) { + //does not fit in child, go on + continue; + } + + } + + if (p_baker->bake_cells[p_idx].childs[i]==Baker::CHILD_EMPTY) { + //sub cell must be created + + uint32_t child_idx = p_baker->bake_cells.size(); + p_baker->bake_cells[p_idx].childs[i]=child_idx; + p_baker->bake_cells.resize( p_baker->bake_cells.size() + 1); + p_baker->bake_cells[child_idx].level=p_level+1; + + } + + + _plot_face(p_baker->bake_cells[p_idx].childs[i],p_level+1,nx,ny,nz,p_vtx,p_uv,p_material,aabb,p_baker); + } + } +} + + + +void GIProbe::_fixup_plot(int p_idx, int p_level,int p_x,int p_y, int p_z,Baker *p_baker) { + + + + if (p_level==p_baker->cell_subdiv-1) { + + p_baker->leaf_voxel_count++; + float alpha = p_baker->bake_cells[p_idx].alpha; + + p_baker->bake_cells[p_idx].albedo[0]/=alpha; + p_baker->bake_cells[p_idx].albedo[1]/=alpha; + p_baker->bake_cells[p_idx].albedo[2]/=alpha; + + //transfer emission to light + p_baker->bake_cells[p_idx].emission[0]/=alpha; + p_baker->bake_cells[p_idx].emission[1]/=alpha; + p_baker->bake_cells[p_idx].emission[2]/=alpha; + + p_baker->bake_cells[p_idx].normal[0]/=alpha; + p_baker->bake_cells[p_idx].normal[1]/=alpha; + p_baker->bake_cells[p_idx].normal[2]/=alpha; + + Vector3 n(p_baker->bake_cells[p_idx].normal[0],p_baker->bake_cells[p_idx].normal[1],p_baker->bake_cells[p_idx].normal[2]); + if (n.length()<0.01) { + //too much fight over normal, zero it + p_baker->bake_cells[p_idx].normal[0]=0; + p_baker->bake_cells[p_idx].normal[1]=0; + p_baker->bake_cells[p_idx].normal[2]=0; + } else { + n.normalize(); + p_baker->bake_cells[p_idx].normal[0]=n.x; + p_baker->bake_cells[p_idx].normal[1]=n.y; + p_baker->bake_cells[p_idx].normal[2]=n.z; + } + + + p_baker->bake_cells[p_idx].alpha=1.0; + + /* + //remove neighbours from used sides + + for(int n=0;n<6;n++) { + + int ofs[3]={0,0,0}; + + ofs[n/2]=(n&1)?1:-1; + + //convert to x,y,z on this level + int x=p_x; + int y=p_y; + int z=p_z; + + x+=ofs[0]; + y+=ofs[1]; + z+=ofs[2]; + + int ofs_x=0; + int ofs_y=0; + int ofs_z=0; + int size = 1<<p_level; + int half=size/2; + + + if (x<0 || x>=size || y<0 || y>=size || z<0 || z>=size) { + //neighbour is out, can't use it + p_baker->bake_cells[p_idx].used_sides&=~(1<<uint32_t(n)); + continue; + } + + uint32_t neighbour=0; + + for(int i=0;i<p_baker->cell_subdiv-1;i++) { + + Baker::Cell *bc = &p_baker->bake_cells[neighbour]; + + int child = 0; + if (x >= ofs_x + half) { + child|=1; + ofs_x+=half; + } + if (y >= ofs_y + half) { + child|=2; + ofs_y+=half; + } + if (z >= ofs_z + half) { + child|=4; + ofs_z+=half; + } + + neighbour = bc->childs[child]; + if (neighbour==Baker::CHILD_EMPTY) { + break; + } + + half>>=1; + } + + if (neighbour!=Baker::CHILD_EMPTY) { + p_baker->bake_cells[p_idx].used_sides&=~(1<<uint32_t(n)); + } + } + */ + } else { + + + //go down + + float alpha_average=0; + int half = (1<<(p_baker->cell_subdiv-1)) >> (p_level+1); + for(int i=0;i<8;i++) { + + uint32_t child = p_baker->bake_cells[p_idx].childs[i]; + + if (child==Baker::CHILD_EMPTY) + continue; + + + int nx=p_x; + int ny=p_y; + int nz=p_z; + + if (i&1) + nx+=half; + if (i&2) + ny+=half; + if (i&4) + nz+=half; + + _fixup_plot(child,p_level+1,nx,ny,nz,p_baker); + alpha_average+=p_baker->bake_cells[child].alpha; + } + + p_baker->bake_cells[p_idx].alpha=alpha_average/8.0; + p_baker->bake_cells[p_idx].emission[0]=0; + p_baker->bake_cells[p_idx].emission[1]=0; + p_baker->bake_cells[p_idx].emission[2]=0; + p_baker->bake_cells[p_idx].normal[0]=0; + p_baker->bake_cells[p_idx].normal[1]=0; + p_baker->bake_cells[p_idx].normal[2]=0; + p_baker->bake_cells[p_idx].albedo[0]=0; + p_baker->bake_cells[p_idx].albedo[1]=0; + p_baker->bake_cells[p_idx].albedo[2]=0; + + } + +} + + + +Vector<Color> GIProbe::_get_bake_texture(Image &p_image,const Color& p_color) { + + Vector<Color> ret; + + if (p_image.empty()) { + + ret.resize(bake_texture_size*bake_texture_size); + for(int i=0;i<bake_texture_size*bake_texture_size;i++) { + ret[i]=p_color; + } + + return ret; + } + + p_image.convert(Image::FORMAT_RGBA8); + p_image.resize(bake_texture_size,bake_texture_size,Image::INTERPOLATE_CUBIC); + + + DVector<uint8_t>::Read r = p_image.get_data().read(); + ret.resize(bake_texture_size*bake_texture_size); + + for(int i=0;i<bake_texture_size*bake_texture_size;i++) { + Color c; + c.r = r[i*4+0]/255.0; + c.g = r[i*4+1]/255.0; + c.b = r[i*4+2]/255.0; + c.a = r[i*4+3]/255.0; + ret[i]=c; + + } + + return ret; +} + + +GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_material,Baker *p_baker) { + + //this way of obtaining materials is inaccurate and also does not support some compressed formats very well + Ref<FixedSpatialMaterial> mat = p_material; + + Ref<Material> material = mat; //hack for now + + if (p_baker->material_cache.has(material)) { + return p_baker->material_cache[material]; + } + + Baker::MaterialCache mc; + + if (mat.is_valid()) { + + + Ref<ImageTexture> albedo_tex = mat->get_texture(FixedSpatialMaterial::TEXTURE_ALBEDO); + + Image img_albedo; + if (albedo_tex.is_valid()) { + + img_albedo = albedo_tex->get_data(); + } + + mc.albedo=_get_bake_texture(img_albedo,mat->get_albedo()); + + Ref<ImageTexture> emission_tex = mat->get_texture(FixedSpatialMaterial::TEXTURE_EMISSION); + + Color emission_col = mat->get_emission(); + emission_col.r*=mat->get_emission_energy(); + emission_col.g*=mat->get_emission_energy(); + emission_col.b*=mat->get_emission_energy(); + + Image img_emission; + + if (emission_tex.is_valid()) { + + img_emission = emission_tex->get_data(); + } + + mc.emission=_get_bake_texture(img_emission,emission_col); + + } else { + Image empty; + + mc.albedo=_get_bake_texture(empty,Color(0.7,0.7,0.7)); + mc.emission=_get_bake_texture(empty,Color(0,0,0)); + + + } + + p_baker->material_cache[p_material]=mc; + return mc; + + +} + +void GIProbe::_plot_mesh(const Transform& p_xform, Ref<Mesh>& p_mesh, Baker *p_baker) { + + + for(int i=0;i<p_mesh->get_surface_count();i++) { + + if (p_mesh->surface_get_primitive_type(i)!=Mesh::PRIMITIVE_TRIANGLES) + continue; //only triangles + + Baker::MaterialCache material = _get_material_cache(p_mesh->surface_get_material(i),p_baker); + + Array a = p_mesh->surface_get_arrays(i); + + + DVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; + DVector<Vector3>::Read vr=vertices.read(); + DVector<Vector2> uv = a[Mesh::ARRAY_TEX_UV]; + DVector<Vector2>::Read uvr; + DVector<int> index = a[Mesh::ARRAY_INDEX]; + + bool read_uv=false; + + if (uv.size()) { + + uvr=uv.read(); + read_uv=true; + } + + if (index.size()) { + + int facecount = index.size()/3; + DVector<int>::Read ir=index.read(); + + for(int j=0;j<facecount;j++) { + + Vector3 vtxs[3]; + Vector2 uvs[3]; + + for(int k=0;k<3;k++) { + vtxs[k]=p_xform.xform(vr[ir[j*3+k]]); + } + + if (read_uv) { + for(int k=0;k<3;k++) { + uvs[k]=uvr[ir[j*3+k]]; + } + } + + //test against original bounds + if (!fast_tri_box_overlap(-extents,extents*2,vtxs)) + continue; + //plot + _plot_face(0,0,0,0,0,vtxs,uvs,material,p_baker->po2_bounds,p_baker); + } + + + + } else { + + int facecount = vertices.size()/3; + + for(int j=0;j<facecount;j++) { + + Vector3 vtxs[3]; + Vector2 uvs[3]; + + for(int k=0;k<3;k++) { + vtxs[k]=p_xform.xform(vr[j*3+k]); + } + + if (read_uv) { + for(int k=0;k<3;k++) { + uvs[k]=uvr[j*3+k]; + } + } + + //test against original bounds + if (!fast_tri_box_overlap(-extents,extents*2,vtxs)) + continue; + //plot face + _plot_face(0,0,0,0,0,vtxs,uvs,material,p_baker->po2_bounds,p_baker); + } + + } + } +} + + + +void GIProbe::_find_meshes(Node *p_at_node,Baker *p_baker){ + + MeshInstance *mi = p_at_node->cast_to<MeshInstance>(); + if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT)) { + Ref<Mesh> mesh = mi->get_mesh(); + if (mesh.is_valid()) { + + AABB aabb = mesh->get_aabb(); + + Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform(); + + if (AABB(-extents,extents*2).intersects(xf.xform(aabb))) { + Baker::PlotMesh pm; + pm.local_xform=xf; + pm.mesh=mesh; + p_baker->mesh_list.push_back(pm); + + } + } + } + + for(int i=0;i<p_at_node->get_child_count();i++) { + + Node *child = p_at_node->get_child(i); + if (!child->get_owner()) + continue; //maybe a helper + + _find_meshes(child,p_baker); + + } +} + + + + +void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug){ + + Baker baker; + + static const int subdiv_value[SUBDIV_MAX]={7,8,9,10}; + + baker.cell_subdiv=subdiv_value[subdiv]; + baker.bake_cells.resize(1); + + //find out the actual real bounds, power of 2, which gets the highest subdivision + baker.po2_bounds=AABB(-extents,extents*2.0); + int longest_axis = baker.po2_bounds.get_longest_axis_index(); + baker.axis_cell_size[longest_axis]=(1<<(baker.cell_subdiv-1)); + baker.leaf_voxel_count=0; + + for(int i=0;i<3;i++) { + + if (i==longest_axis) + continue; + + baker.axis_cell_size[i]=baker.axis_cell_size[longest_axis]; + float axis_size = baker.po2_bounds.size[longest_axis]; + + //shrink until fit subdiv + while (axis_size/2.0 >= baker.po2_bounds.size[i]) { + axis_size/=2.0; + baker.axis_cell_size[i]>>=1; + } + + baker.po2_bounds.size[i]=baker.po2_bounds.size[longest_axis]; + } + + + + Transform to_bounds; + to_bounds.basis.scale(Vector3(baker.po2_bounds.size[longest_axis],baker.po2_bounds.size[longest_axis],baker.po2_bounds.size[longest_axis])); + to_bounds.origin=baker.po2_bounds.pos; + + Transform to_grid; + to_grid.basis.scale(Vector3(baker.axis_cell_size[longest_axis],baker.axis_cell_size[longest_axis],baker.axis_cell_size[longest_axis])); + + baker.to_cell_space = to_grid * to_bounds.affine_inverse(); + + + _find_meshes(p_from_node?p_from_node:get_parent(),&baker); + + + + int pmc=0; + + for(List<Baker::PlotMesh>::Element *E=baker.mesh_list.front();E;E=E->next()) { + + print_line("plotting mesh "+itos(pmc++)+"/"+itos(baker.mesh_list.size())); + + _plot_mesh(E->get().local_xform,E->get().mesh,&baker); + } + + _fixup_plot(0,0,0,0,0,&baker); + + //create the data for visual server + + DVector<int> data; + + data.resize( 16+(8+1+1+1+1)*baker.bake_cells.size() ); //4 for header, rest for rest. + + { + DVector<int>::Write w = data.write(); + + uint32_t * w32 = (uint32_t*)w.ptr(); + + w32[0]=0;//version + w32[1]=baker.cell_subdiv; //subdiv + w32[2]=baker.axis_cell_size[0]; + w32[3]=baker.axis_cell_size[1]; + w32[4]=baker.axis_cell_size[2]; + w32[5]=baker.bake_cells.size(); + w32[6]=baker.leaf_voxel_count; + + int ofs=16; + + for(int i=0;i<baker.bake_cells.size();i++) { + + for(int j=0;j<8;j++) { + w32[ofs++]=baker.bake_cells[i].childs[j]; + } + + { //albedo + uint32_t rgba=uint32_t(CLAMP(baker.bake_cells[i].albedo[0]*255.0,0,255))<<16; + rgba|=uint32_t(CLAMP(baker.bake_cells[i].albedo[1]*255.0,0,255))<<8; + rgba|=uint32_t(CLAMP(baker.bake_cells[i].albedo[2]*255.0,0,255))<<0; + + w32[ofs++]=rgba; + + + } + { //emission + + Vector3 e(baker.bake_cells[i].emission[0],baker.bake_cells[i].emission[1],baker.bake_cells[i].emission[2]); + float l = e.length(); + if (l>0) { + e.normalize(); + l=CLAMP(l/8.0,0,1.0); + } + + uint32_t em=uint32_t(CLAMP(e[0]*255,0,255))<<24; + em|=uint32_t(CLAMP(e[1]*255,0,255))<<16; + em|=uint32_t(CLAMP(e[2]*255,0,255))<<8; + em|=uint32_t(CLAMP(l*255,0,255)); + + w32[ofs++]=em; + } + + //w32[ofs++]=baker.bake_cells[i].used_sides; + { //normal + + Vector3 n(baker.bake_cells[i].normal[0],baker.bake_cells[i].normal[1],baker.bake_cells[i].normal[2]); + n=n*Vector3(0.5,0.5,0.5)+Vector3(0.5,0.5,0.5); + uint32_t norm=0; + + + norm|=uint32_t(CLAMP( n.x*255.0, 0, 255))<<16; + norm|=uint32_t(CLAMP( n.y*255.0, 0, 255))<<8; + norm|=uint32_t(CLAMP( n.z*255.0, 0, 255))<<0; + + w32[ofs++]=norm; + } + + { + uint16_t alpha = CLAMP(uint32_t(baker.bake_cells[i].alpha*65535.0),0,65535); + uint16_t level = baker.bake_cells[i].level; + + w32[ofs++] = (uint32_t(level)<<16)|uint32_t(alpha); + } + + } + + } + + Ref<GIProbeData> probe_data; + probe_data.instance(); + probe_data->set_bounds(AABB(-extents,extents*2.0)); + probe_data->set_cell_size(baker.po2_bounds.size[longest_axis]/baker.axis_cell_size[longest_axis]); + probe_data->set_dynamic_data(data); + probe_data->set_dynamic_range(dynamic_range); + probe_data->set_energy(energy); + probe_data->set_interior(interior); + probe_data->set_compress(compress); + probe_data->set_to_cell_xform(baker.to_cell_space); + + set_probe_data(probe_data); + + + if (p_create_visual_debug) { + // _create_debug_mesh(&baker); + } + + + +} + + +void GIProbe::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb,Ref<MultiMesh> &p_multimesh,int &idx,Baker *p_baker) { + + + if (p_level==p_baker->cell_subdiv-1) { + + Vector3 center = p_aabb.pos+p_aabb.size*0.5; + Transform xform; + xform.origin=center; + xform.basis.scale(p_aabb.size*0.5); + p_multimesh->set_instance_transform(idx,xform); + Color col=Color(p_baker->bake_cells[p_idx].albedo[0],p_baker->bake_cells[p_idx].albedo[1],p_baker->bake_cells[p_idx].albedo[2]); + p_multimesh->set_instance_color(idx,col); + + idx++; + + } else { + + for(int i=0;i<8;i++) { + + if (p_baker->bake_cells[p_idx].childs[i]==Baker::CHILD_EMPTY) + continue; + + AABB aabb=p_aabb; + aabb.size*=0.5; + + if (i&1) + aabb.pos.x+=aabb.size.x; + if (i&2) + aabb.pos.y+=aabb.size.y; + if (i&4) + aabb.pos.z+=aabb.size.z; + + _debug_mesh(p_baker->bake_cells[p_idx].childs[i],p_level+1,aabb,p_multimesh,idx,p_baker); + } + + } + +} + + +void GIProbe::_create_debug_mesh(Baker *p_baker) { + + Ref<MultiMesh> mm; + mm.instance(); + + mm->set_transform_format(MultiMesh::TRANSFORM_3D); + mm->set_color_format(MultiMesh::COLOR_8BIT); + print_line("leaf voxels: "+itos(p_baker->leaf_voxel_count)); + mm->set_instance_count(p_baker->leaf_voxel_count); + + Ref<Mesh> mesh; + mesh.instance(); + + { + Array arr; + arr.resize(Mesh::ARRAY_MAX); + + DVector<Vector3> vertices; + DVector<Color> colors; + + int vtx_idx=0; + #define ADD_VTX(m_idx);\ + vertices.push_back( face_points[m_idx] );\ + colors.push_back( Color(1,1,1,1) );\ + vtx_idx++;\ + + for (int i=0;i<6;i++) { + + + Vector3 face_points[4]; + + for (int j=0;j<4;j++) { + + float v[3]; + v[0]=1.0; + v[1]=1-2*((j>>1)&1); + v[2]=v[1]*(1-2*(j&1)); + + for (int k=0;k<3;k++) { + + if (i<3) + face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1); + else + face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); + } + } + + //tri 1 + ADD_VTX(0); + ADD_VTX(1); + ADD_VTX(2); + //tri 2 + ADD_VTX(2); + ADD_VTX(3); + ADD_VTX(0); + + } + + + arr[Mesh::ARRAY_VERTEX]=vertices; + arr[Mesh::ARRAY_COLOR]=colors; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES,arr); + } + + { + Ref<FixedSpatialMaterial> fsm; + fsm.instance(); + fsm->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR,true); + fsm->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true); + fsm->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true); + fsm->set_albedo(Color(1,1,1,1)); + + mesh->surface_set_material(0,fsm); + } + + mm->set_mesh(mesh); + + + int idx=0; + _debug_mesh(0,0,p_baker->po2_bounds,mm,idx,p_baker); + + MultiMeshInstance *mmi = memnew( MultiMeshInstance ); + mmi->set_multimesh(mm); + add_child(mmi); + if (get_tree()->get_edited_scene_root()==this){ + mmi->set_owner(this); + } else { + mmi->set_owner(get_owner()); + + } + +} + +void GIProbe::_debug_bake() { + + bake(NULL,true); +} + +AABB GIProbe::get_aabb() const { + + return AABB(-extents,extents*2); +} + +DVector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const { + + return DVector<Face3>(); +} + +void GIProbe::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_probe_data","data"),&GIProbe::set_probe_data); + ObjectTypeDB::bind_method(_MD("get_probe_data"),&GIProbe::get_probe_data); + + ObjectTypeDB::bind_method(_MD("set_subdiv","subdiv"),&GIProbe::set_subdiv); + ObjectTypeDB::bind_method(_MD("get_subdiv"),&GIProbe::get_subdiv); + + ObjectTypeDB::bind_method(_MD("set_extents","extents"),&GIProbe::set_extents); + ObjectTypeDB::bind_method(_MD("get_extents"),&GIProbe::get_extents); + + ObjectTypeDB::bind_method(_MD("set_dynamic_range","max"),&GIProbe::set_dynamic_range); + ObjectTypeDB::bind_method(_MD("get_dynamic_range"),&GIProbe::get_dynamic_range); + + ObjectTypeDB::bind_method(_MD("set_energy","max"),&GIProbe::set_energy); + ObjectTypeDB::bind_method(_MD("get_energy"),&GIProbe::get_energy); + + ObjectTypeDB::bind_method(_MD("set_interior","enable"),&GIProbe::set_interior); + ObjectTypeDB::bind_method(_MD("is_interior"),&GIProbe::is_interior); + + ObjectTypeDB::bind_method(_MD("set_compress","enable"),&GIProbe::set_compress); + ObjectTypeDB::bind_method(_MD("is_compressed"),&GIProbe::is_compressed); + + ObjectTypeDB::bind_method(_MD("bake","from_node","create_visual_debug"),&GIProbe::bake,DEFVAL(Variant()),DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("debug_bake"),&GIProbe::_debug_bake); + ObjectTypeDB::set_method_flags(get_type_static(),_SCS("debug_bake"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); + + ADD_PROPERTY( PropertyInfo(Variant::INT,"subdiv",PROPERTY_HINT_ENUM,"64,128,256,512"),_SCS("set_subdiv"),_SCS("get_subdiv")); + ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"extents"),_SCS("set_extents"),_SCS("get_extents")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"dynamic_range",PROPERTY_HINT_RANGE,"1,16,1"),_SCS("set_dynamic_range"),_SCS("get_dynamic_range")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_energy"),_SCS("get_energy")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"interior"),_SCS("set_interior"),_SCS("is_interior")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"compress"),_SCS("set_compress"),_SCS("is_compressed")); + ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"data",PROPERTY_HINT_RESOURCE_TYPE,"GIProbeData"),_SCS("set_probe_data"),_SCS("get_probe_data")); + + + BIND_CONSTANT( SUBDIV_64 ); + BIND_CONSTANT( SUBDIV_128 ); + BIND_CONSTANT( SUBDIV_256 ); + BIND_CONSTANT( SUBDIV_MAX ); + +} + +GIProbe::GIProbe() { + + subdiv=SUBDIV_128; + dynamic_range=4; + energy=1.0; + extents=Vector3(10,10,10); + color_scan_cell_width=4; + bake_texture_size=128; + interior=false; + compress=false; + + gi_probe = VS::get_singleton()->gi_probe_create(); + + +} + +GIProbe::~GIProbe() { + + +} diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h new file mode 100644 index 0000000000..59747761b8 --- /dev/null +++ b/scene/3d/gi_probe.h @@ -0,0 +1,190 @@ +#ifndef GIPROBE_H +#define GIPROBE_H + +#include "scene/3d/visual_instance.h" +#include "multimesh_instance.h" + +class GIProbeData : public Resource { + + OBJ_TYPE(GIProbeData,Resource); + + RID probe; + +protected: + + static void _bind_methods(); +public: + + + + void set_bounds(const AABB& p_bounds); + AABB get_bounds() const; + + void set_cell_size(float p_size); + float get_cell_size() const; + + void set_to_cell_xform(const Transform& p_xform); + Transform get_to_cell_xform() const; + + void set_dynamic_data(const DVector<int>& p_data); + DVector<int> get_dynamic_data() const; + + void set_dynamic_range(int p_range); + int get_dynamic_range() const; + + void set_energy(float p_range); + float get_energy() const; + + void set_interior(bool p_enable); + bool is_interior() const; + + void set_compress(bool p_enable); + bool is_compressed() const; + + virtual RID get_rid() const; + + GIProbeData(); + ~GIProbeData(); +}; + + + +class GIProbe : public VisualInstance { + OBJ_TYPE(GIProbe,VisualInstance); +public: + enum Subdiv{ + SUBDIV_64, + SUBDIV_128, + SUBDIV_256, + SUBDIV_512, + SUBDIV_MAX + + }; +private: + + //stuff used for bake + struct Baker { + + enum { + CHILD_EMPTY=0xFFFFFFFF + }; + struct Cell { + + uint32_t childs[8]; + float albedo[3]; //albedo in RGB24 + float emission[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast) + float normal[3]; + uint32_t used_sides; + float alpha; //used for upsampling + int level; + + Cell() { + for(int i=0;i<8;i++) { + childs[i]=CHILD_EMPTY; + } + + for(int i=0;i<3;i++) { + emission[i]=0; + albedo[i]=0; + normal[i]=0; + } + alpha=0; + used_sides=0; + level=0; + } + }; + + Vector<Cell> bake_cells; + int cell_subdiv; + + struct MaterialCache { + //128x128 textures + Vector<Color> albedo; + Vector<Color> emission; + }; + + + Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color); + Map<Ref<Material>,MaterialCache> material_cache; + MaterialCache _get_material_cache(Ref<Material> p_material); + int leaf_voxel_count; + + + AABB po2_bounds; + int axis_cell_size[3]; + + struct PlotMesh { + Ref<Mesh> mesh; + Transform local_xform; + }; + + Transform to_cell_space; + + List<PlotMesh> mesh_list; + }; + + + Ref<GIProbeData> probe_data; + + RID gi_probe; + + Subdiv subdiv; + Vector3 extents; + int dynamic_range; + float energy; + bool interior; + bool compress; + + int color_scan_cell_width; + int bake_texture_size; + + Vector<Color> _get_bake_texture(Image &p_image,const Color& p_color); + Baker::MaterialCache _get_material_cache(Ref<Material> p_material,Baker *p_baker); + void _plot_face(int p_idx, int p_level, int p_x,int p_y,int p_z,const Vector3 *p_vtx, const Vector2* p_uv, const Baker::MaterialCache& p_material, const AABB &p_aabb,Baker *p_baker); + void _plot_mesh(const Transform& p_xform, Ref<Mesh>& p_mesh, Baker *p_baker); + void _find_meshes(Node *p_at_node,Baker *p_baker); + void _fixup_plot(int p_idx, int p_level,int p_x,int p_y, int p_z,Baker *p_baker); + + void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb,Ref<MultiMesh> &p_multimesh,int &idx,Baker *p_baker); + void _create_debug_mesh(Baker *p_baker); + + void _debug_bake(); + +protected: + + static void _bind_methods(); +public: + + void set_probe_data(const Ref<GIProbeData>& p_data); + Ref<GIProbeData> get_probe_data() const; + + void set_subdiv(Subdiv p_subdiv); + Subdiv get_subdiv() const; + + void set_extents(const Vector3& p_extents); + Vector3 get_extents() const; + + void set_dynamic_range(int p_dynamic_range); + int get_dynamic_range() const; + + void set_energy(float p_energy); + float get_energy() const; + + void set_interior(bool p_enable); + bool is_interior() const; + + void set_compress(bool p_enable); + bool is_compressed() const; + + void bake(Node *p_from_node=NULL,bool p_create_visual_debug=false); + + virtual AABB get_aabb() const; + virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const; + + GIProbe(); + ~GIProbe(); +}; + +VARIANT_ENUM_CAST(GIProbe::Subdiv) + +#endif // GIPROBE_H diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index d9e153c4f5..7a0db6c174 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -30,310 +30,105 @@ #include "globals.h" #include "scene/resources/surface_tool.h" +#include "baked_light_instance.h" -static const char* _light_param_names[VS::LIGHT_PARAM_MAX]={ - "params/spot_attenuation", - "params/spot_angle", - "params/radius", - "params/energy", - "params/attenuation", - "shadow/darkening", - "shadow/z_offset", - "shadow/z_slope_scale", - "shadow/esm_multiplier", - "shadow/blur_passes" -}; - -void Light::set_parameter(Parameter p_param, float p_value) { +bool Light::_can_gizmo_scale() const { - ERR_FAIL_INDEX(p_param, PARAM_MAX); - vars[p_param]=p_value; - VisualServer::get_singleton()->light_set_param(light,(VisualServer::LightParam)p_param,p_value); - if (p_param==PARAM_RADIUS || p_param==PARAM_SPOT_ANGLE) - update_gizmo(); - _change_notify(_light_param_names[p_param]); -// _change_notify(_param_names[p_param]); + return false; } -float Light::get_parameter(Parameter p_param) const { - ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); - return vars[p_param]; +void Light::set_param(Param p_param, float p_value) { -} - -void Light::set_color(LightColor p_color, const Color& p_value) { + ERR_FAIL_INDEX(p_param,PARAM_MAX); + param[p_param]=p_value; - ERR_FAIL_INDEX(p_color, 3); - colors[p_color]=p_value; - VisualServer::get_singleton()->light_set_color(light,(VisualServer::LightColor)p_color,p_value); - //_change_notify(_color_names[p_color]); + VS::get_singleton()->light_set_param(light,VS::LightParam(p_param),p_value); -} -Color Light::get_color(LightColor p_color) const { + if (p_param==PARAM_SPOT_ANGLE || p_param==PARAM_RANGE) { + update_gizmo();; + } - ERR_FAIL_INDEX_V(p_color, 3, Color()); - return colors[p_color]; } +float Light::get_param(Param p_param) const{ -void Light::set_project_shadows(bool p_enabled) { + ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0); + return param[p_param]; - shadows=p_enabled; - VisualServer::get_singleton()->light_set_shadow(light, p_enabled); - _change_notify("shadow"); } -bool Light::has_project_shadows() const { - return shadows; -} +void Light::set_shadow(bool p_enable){ -void Light::set_projector(const Ref<Texture>& p_projector) { + shadow=p_enable; + VS::get_singleton()->light_set_shadow(light,p_enable); - projector=p_projector; - VisualServer::get_singleton()->light_set_projector(light, projector.is_null()?RID():projector->get_rid()); } +bool Light::has_shadow() const{ -Ref<Texture> Light::get_projector() const { - - return projector; + return shadow; } +void Light::set_negative(bool p_enable){ -bool Light::_can_gizmo_scale() const { - - return false; + negative=p_enable; + VS::get_singleton()->light_set_negative(light,p_enable); } +bool Light::is_negative() const{ - -static void _make_sphere(int p_lats, int p_lons, float p_radius, Ref<SurfaceTool> p_tool) { - - - p_tool->begin(Mesh::PRIMITIVE_TRIANGLES); - - for(int i = 1; i <= p_lats; i++) { - double lat0 = Math_PI * (-0.5 + (double) (i - 1) / p_lats); - double z0 = Math::sin(lat0); - double zr0 = Math::cos(lat0); - - double lat1 = Math_PI * (-0.5 + (double) i / p_lats); - double z1 = Math::sin(lat1); - double zr1 = Math::cos(lat1); - - for(int j = p_lons; j >= 1; j--) { - - double lng0 = 2 * Math_PI * (double) (j - 1) / p_lons; - double x0 = Math::cos(lng0); - double y0 = Math::sin(lng0); - - double lng1 = 2 * Math_PI * (double) (j) / p_lons; - double x1 = Math::cos(lng1); - double y1 = Math::sin(lng1); - - - Vector3 v[4]={ - Vector3(x1 * zr0, z0, y1 *zr0), - Vector3(x1 * zr1, z1, y1 *zr1), - Vector3(x0 * zr1, z1, y0 *zr1), - Vector3(x0 * zr0, z0, y0 *zr0) - }; - -#define ADD_POINT(m_idx) \ - p_tool->add_normal(v[m_idx]);\ - p_tool->add_vertex(v[m_idx]*p_radius); - - ADD_POINT(0); - ADD_POINT(1); - ADD_POINT(2); - - ADD_POINT(2); - ADD_POINT(3); - ADD_POINT(0); - } - } - + return negative; } -RES Light::_get_gizmo_geometry() const { - - - Ref<FixedMaterial> mat_area( memnew( FixedMaterial )); - - mat_area->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.7,0.6,0.0,0.05) ); - mat_area->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.7,0.7,0.7) ); - mat_area->set_blend_mode( Material::BLEND_MODE_ADD ); - mat_area->set_flag(Material::FLAG_DOUBLE_SIDED,true); -// mat_area->set_hint(Material::HINT_NO_DEPTH_DRAW,true); - - Ref<FixedMaterial> mat_light( memnew( FixedMaterial )); - - mat_light->set_parameter( FixedMaterial::PARAM_DIFFUSE, Color(1.0,1.0,0.8,0.9) ); - mat_light->set_flag(Material::FLAG_UNSHADED,true); - - Ref< Mesh > mesh; - - Ref<SurfaceTool> surftool( memnew( SurfaceTool )); - - switch(type) { - - case VisualServer::LIGHT_DIRECTIONAL: { - - - mat_area->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.9,0.8,0.1,0.8) ); - mat_area->set_blend_mode( Material::BLEND_MODE_MIX); - mat_area->set_flag(Material::FLAG_DOUBLE_SIDED,false); - mat_area->set_flag(Material::FLAG_UNSHADED,true); - - _make_sphere( 5,5,0.6, surftool ); - surftool->set_material(mat_light); - mesh=surftool->commit(mesh); - - // float radius=1; - - surftool->begin(Mesh::PRIMITIVE_TRIANGLES); - - const int arrow_points=5; - Vector3 arrow[arrow_points]={ - Vector3(0,0,2), - Vector3(1,1,2), - Vector3(1,1,-1), - Vector3(2,2,-1), - Vector3(0,0,-3) - }; - - int arrow_sides=4; +void Light::set_cull_mask(uint32_t p_cull_mask){ + cull_mask=p_cull_mask; + VS::get_singleton()->light_set_cull_mask(light,p_cull_mask); - for(int i = 0; i < arrow_sides ; i++) { - - - Matrix3 ma(Vector3(0,0,1),Math_PI*2*float(i)/arrow_sides); - Matrix3 mb(Vector3(0,0,1),Math_PI*2*float(i+1)/arrow_sides); - - - for(int j=0;j<arrow_points-1;j++) { - - Vector3 points[4]={ - ma.xform(arrow[j]), - mb.xform(arrow[j]), - mb.xform(arrow[j+1]), - ma.xform(arrow[j+1]), - }; - - Vector3 n = Plane(points[0],points[1],points[2]).normal; - - surftool->add_normal(n); - surftool->add_vertex(points[0]); - surftool->add_normal(n); - surftool->add_vertex(points[1]); - surftool->add_normal(n); - surftool->add_vertex(points[2]); - - surftool->add_normal(n); - surftool->add_vertex(points[0]); - surftool->add_normal(n); - surftool->add_vertex(points[2]); - surftool->add_normal(n); - surftool->add_vertex(points[3]); - - - } - - - } - - surftool->set_material(mat_area); - mesh=surftool->commit(mesh); - - - - } break; - case VisualServer::LIGHT_OMNI: { - - - _make_sphere( 20,20,vars[PARAM_RADIUS], surftool ); - surftool->set_material(mat_area); - mesh=surftool->commit(mesh); - _make_sphere(5,5, 0.1, surftool ); - surftool->set_material(mat_light); - mesh=surftool->commit(mesh); - } break; - - case VisualServer::LIGHT_SPOT: { - - _make_sphere( 5,5,0.1, surftool ); - surftool->set_material(mat_light); - mesh=surftool->commit(mesh); - - // make cone - int points=24; - float len=vars[PARAM_RADIUS]; - float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len; - - surftool->begin(Mesh::PRIMITIVE_TRIANGLES); - - for(int i = 0; i < points; i++) { - - float x0=Math::sin(i * Math_PI * 2 / points); - float y0=Math::cos(i * Math_PI * 2 / points); - float x1=Math::sin((i+1) * Math_PI * 2 / points); - float y1=Math::cos((i+1) * Math_PI * 2 / points); - - Vector3 v1=Vector3(x0*size,y0*size,-len).normalized()*len; - Vector3 v2=Vector3(x1*size,y1*size,-len).normalized()*len; - - Vector3 v3=Vector3(0,0,0); - Vector3 v4=Vector3(0,0,v1.z); - - Vector3 n = Plane(v1,v2,v3).normal; - - - surftool->add_normal(n); - surftool->add_vertex(v1); - surftool->add_normal(n); - surftool->add_vertex(v2); - surftool->add_normal(n); - surftool->add_vertex(v3); +} +uint32_t Light::get_cull_mask() const{ - n=Vector3(0,0,-1); + return cull_mask; +} - surftool->add_normal(n); - surftool->add_vertex(v1); - surftool->add_normal(n); - surftool->add_vertex(v2); - surftool->add_normal(n); - surftool->add_vertex(v4); +void Light::set_color(const Color& p_color){ + color=p_color; + VS::get_singleton()->light_set_color(light,p_color); +} +Color Light::get_color() const{ - } + return color; +} - surftool->set_material(mat_area); - mesh=surftool->commit(mesh); +void Light::set_shadow_color(const Color& p_shadow_color){ + shadow_color=p_shadow_color; + VS::get_singleton()->light_set_shadow_color(light,p_shadow_color); +} - } break; - } +Color Light::get_shadow_color() const{ - return mesh; + return shadow_color; } AABB Light::get_aabb() const { + if (type==VisualServer::LIGHT_DIRECTIONAL) { return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) ); } else if (type==VisualServer::LIGHT_OMNI) { - return AABB( Vector3(-1,-1,-1) * vars[PARAM_RADIUS], Vector3(2, 2, 2 ) * vars[PARAM_RADIUS]); + return AABB( Vector3(-1,-1,-1) * param[PARAM_RANGE], Vector3(2, 2, 2 ) * param[PARAM_RANGE]); } else if (type==VisualServer::LIGHT_SPOT) { - float len=vars[PARAM_RADIUS]; - float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len; + float len=param[PARAM_RANGE]; + float size=Math::tan(Math::deg2rad(param[PARAM_SPOT_ANGLE]))*len; return AABB( Vector3( -size,-size,-len ), Vector3( size*2, size*2, len ) ); } @@ -346,89 +141,6 @@ DVector<Face3> Light::get_faces(uint32_t p_usage_flags) const { } -void Light::set_operator(Operator p_op) { - ERR_FAIL_INDEX(p_op,2); - op=p_op; - VisualServer::get_singleton()->light_set_operator(light,VS::LightOp(op)); - -} - -void Light::set_bake_mode(BakeMode p_bake_mode) { - - bake_mode=p_bake_mode; -} - -Light::BakeMode Light::get_bake_mode() const { - - return bake_mode; -} - - -Light::Operator Light::get_operator() const { - - return op; -} - -void Light::approximate_opengl_attenuation(float p_constant, float p_linear, float p_quadratic,float p_radius_treshold) { - - //this is horrible and must never be used - - float a = p_quadratic * p_radius_treshold; - float b = p_linear * p_radius_treshold; - float c = p_constant * p_radius_treshold -1; - - float radius=10000; - - if(a == 0) { // solve linear - float d = Math::abs(-c/b); - if(d<radius) - radius=d; - - - } else { // solve quadratic - // now ad^2 + bd + c = 0, solve quadratic equation: - - float denominator = 2*a; - - if(denominator != 0) { - - - float root = b*b - 4*a*c; - - if(root >=0) { - - root = sqrt(root); - - float solution1 = fabs( (-b + root) / denominator); - float solution2 = fabs( (-b - root) / denominator); - - if(solution1 > radius) - solution1 = radius; - - if(solution2 > radius) - solution2 = radius; - - radius = (solution1 > solution2 ? solution1 : solution2); - } - } - } - - float energy=1.0; - - /*if (p_constant>0) - energy=1.0/p_constant; //energy is this - else - energy=8.0; // some high number.. -*/ - - if (radius==10000) - radius=100; //bug? - - set_parameter(PARAM_RADIUS,radius); - set_parameter(PARAM_ENERGY,energy); - -} - void Light::_update_visibility() { @@ -436,7 +148,7 @@ void Light::_update_visibility() { return; -bool editor_ok=true; + bool editor_ok=true; #ifdef TOOLS_ENABLED if (editor_only) { @@ -452,7 +164,7 @@ bool editor_ok=true; } #endif - VS::get_singleton()->instance_light_set_enabled(get_instance(),is_visible() && enabled && editor_ok); + //VS::get_singleton()->instance_light_set_enabled(get_instance(),is_visible() && editor_ok); _change_notify("geometry/visible"); } @@ -460,22 +172,40 @@ bool editor_ok=true; void Light::_notification(int p_what) { - if (p_what==NOTIFICATION_ENTER_TREE || p_what==NOTIFICATION_VISIBILITY_CHANGED) { + + if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { + _update_visibility(); + } -} -void Light::set_enabled(bool p_enabled) { + if (p_what==NOTIFICATION_ENTER_TREE) { + _update_visibility(); - enabled=p_enabled; - _update_visibility(); -} + Node *node = this; + + while(node) { + + baked_light=node->cast_to<BakedLight>(); + if (baked_light) { + baked_light->lights.insert(this); + break; + } + + node=node->get_parent(); + } + } -bool Light::is_enabled() const{ + if (p_what==NOTIFICATION_EXIT_TREE) { + + if (baked_light) { + baked_light->lights.erase(this); + } + } - return enabled; } + void Light::set_editor_only(bool p_editor_only) { editor_only=p_editor_only; @@ -490,68 +220,54 @@ bool Light::is_editor_only() const{ void Light::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_parameter","variable","value"), &Light::set_parameter ); - ObjectTypeDB::bind_method(_MD("get_parameter","variable"), &Light::get_parameter ); - ObjectTypeDB::bind_method(_MD("set_color","color","value"), &Light::set_color ); - ObjectTypeDB::bind_method(_MD("get_color","color"), &Light::get_color ); - ObjectTypeDB::bind_method(_MD("set_project_shadows","enable"), &Light::set_project_shadows ); - ObjectTypeDB::bind_method(_MD("has_project_shadows"), &Light::has_project_shadows ); - ObjectTypeDB::bind_method(_MD("set_projector","projector:Texture"), &Light::set_projector ); - ObjectTypeDB::bind_method(_MD("get_projector:Texture"), &Light::get_projector ); - ObjectTypeDB::bind_method(_MD("set_operator","operator"), &Light::set_operator ); - ObjectTypeDB::bind_method(_MD("get_operator"), &Light::get_operator ); - ObjectTypeDB::bind_method(_MD("set_bake_mode","bake_mode"), &Light::set_bake_mode ); - ObjectTypeDB::bind_method(_MD("get_bake_mode"), &Light::get_bake_mode ); - ObjectTypeDB::bind_method(_MD("set_enabled","enabled"), &Light::set_enabled ); - ObjectTypeDB::bind_method(_MD("is_enabled"), &Light::is_enabled ); + ObjectTypeDB::bind_method(_MD("set_editor_only","editor_only"), &Light::set_editor_only ); ObjectTypeDB::bind_method(_MD("is_editor_only"), &Light::is_editor_only ); - ADD_PROPERTY( PropertyInfo( Variant::BOOL, "params/enabled"), _SCS("set_enabled"), _SCS("is_enabled")); - ADD_PROPERTY( PropertyInfo( Variant::BOOL, "params/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only")); - ADD_PROPERTY( PropertyInfo( Variant::INT, "params/bake_mode",PROPERTY_HINT_ENUM,"Disabled,Indirect,Indirect+Shadows,Full"), _SCS("set_bake_mode"), _SCS("get_bake_mode")); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/energy", PROPERTY_HINT_EXP_RANGE, "0,64,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ENERGY ); - /* - if (type == VisualServer::LIGHT_OMNI || type == VisualServer::LIGHT_SPOT) { - ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01")); - ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_RANGE, "0,8,0.01")); - } + ObjectTypeDB::bind_method(_MD("set_param","param","value"), &Light::set_param ); + ObjectTypeDB::bind_method(_MD("get_param","param"), &Light::get_param ); + + ObjectTypeDB::bind_method(_MD("set_shadow","enabled"), &Light::set_shadow ); + ObjectTypeDB::bind_method(_MD("has_shadow"), &Light::has_shadow ); - if (type == VisualServer::LIGHT_SPOT) { - ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/spot_angle", PROPERTY_HINT_RANGE, "0.01,90.0,0.01")); - ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_RANGE, "0,8,0.01")); + ObjectTypeDB::bind_method(_MD("set_negative","enabled"), &Light::set_negative ); + ObjectTypeDB::bind_method(_MD("is_negative"), &Light::is_negative ); - }*/ + ObjectTypeDB::bind_method(_MD("set_cull_mask","cull_mask"), &Light::set_cull_mask ); + ObjectTypeDB::bind_method(_MD("get_cull_mask"), &Light::get_cull_mask ); - ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "colors/diffuse"), _SCS("set_color"), _SCS("get_color"),COLOR_DIFFUSE); - ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "colors/specular"), _SCS("set_color"), _SCS("get_color"),COLOR_SPECULAR); - ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/shadow"), _SCS("set_project_shadows"), _SCS("has_project_shadows")); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/darkening", PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_DARKENING ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/z_offset", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_OFFSET); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/z_slope_scale", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_SLOPE_SCALE); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/esm_multiplier", PROPERTY_HINT_RANGE, "1.0,512.0,0.1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_ESM_MULTIPLIER); - ADD_PROPERTYI( PropertyInfo( Variant::INT, "shadow/blur_passes", PROPERTY_HINT_RANGE, "0,4,1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_BLUR_PASSES); - ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "projector",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_projector"), _SCS("get_projector")); - ADD_PROPERTY( PropertyInfo( Variant::INT, "operator",PROPERTY_HINT_ENUM,"Add,Sub"), _SCS("set_operator"), _SCS("get_operator")); + ObjectTypeDB::bind_method(_MD("set_color","color"), &Light::set_color ); + ObjectTypeDB::bind_method(_MD("get_color"), &Light::get_color ); + ObjectTypeDB::bind_method(_MD("set_shadow_color","shadow_color"), &Light::set_shadow_color ); + ObjectTypeDB::bind_method(_MD("get_shadow_color"), &Light::get_shadow_color ); + + ADD_PROPERTY( PropertyInfo( Variant::COLOR, "light/color",PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_color"), _SCS("get_color")); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/energy",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_ENERGY); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "light/negative"), _SCS("set_negative"), _SCS("is_negative")); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/specular",PROPERTY_HINT_RANGE,"0,1,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SPECULAR); + ADD_PROPERTY( PropertyInfo( Variant::INT, "light/cull_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_cull_mask"), _SCS("get_cull_mask")); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/enabled"), _SCS("set_shadow"), _SCS("has_shadow")); + ADD_PROPERTY( PropertyInfo( Variant::COLOR, "shadow/color",PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_shadow_color"), _SCS("get_shadow_color")); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias",PROPERTY_HINT_RANGE,"-16,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/max_distance",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_MAX_DISTANCE); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editor/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only")); - BIND_CONSTANT( PARAM_RADIUS ); BIND_CONSTANT( PARAM_ENERGY ); + BIND_CONSTANT( PARAM_SPECULAR ); + BIND_CONSTANT( PARAM_RANGE ); BIND_CONSTANT( PARAM_ATTENUATION ); BIND_CONSTANT( PARAM_SPOT_ANGLE ); BIND_CONSTANT( PARAM_SPOT_ATTENUATION ); - BIND_CONSTANT( PARAM_SHADOW_DARKENING ); - BIND_CONSTANT( PARAM_SHADOW_Z_OFFSET ); - - - BIND_CONSTANT( COLOR_DIFFUSE ); - BIND_CONSTANT( COLOR_SPECULAR ); - - BIND_CONSTANT( BAKE_MODE_DISABLED ); - BIND_CONSTANT( BAKE_MODE_INDIRECT ); - BIND_CONSTANT( BAKE_MODE_INDIRECT_AND_SHADOWS ); - BIND_CONSTANT( BAKE_MODE_FULL ); + BIND_CONSTANT( PARAM_SHADOW_MAX_DISTANCE ); + BIND_CONSTANT( PARAM_SHADOW_SPLIT_1_OFFSET ); + BIND_CONSTANT( PARAM_SHADOW_SPLIT_2_OFFSET ); + BIND_CONSTANT( PARAM_SHADOW_SPLIT_3_OFFSET ); + BIND_CONSTANT( PARAM_SHADOW_NORMAL_BIAS ); + BIND_CONSTANT( PARAM_SHADOW_BIAS ); + BIND_CONSTANT( PARAM_SHADOW_BIAS_SPLIT_SCALE ); + BIND_CONSTANT( PARAM_MAX ); } @@ -561,28 +277,29 @@ Light::Light(VisualServer::LightType p_type) { type=p_type; light=VisualServer::get_singleton()->light_create(p_type); + VS::get_singleton()->instance_set_base(get_instance(),light); + + baked_light=NULL; - set_parameter(PARAM_SPOT_ATTENUATION,1.0); - set_parameter(PARAM_SPOT_ANGLE,30.0); - set_parameter(PARAM_RADIUS,2.0); - set_parameter(PARAM_ENERGY,1.0); - set_parameter(PARAM_ATTENUATION,1.0); - set_parameter(PARAM_SHADOW_DARKENING,0.0); - set_parameter(PARAM_SHADOW_Z_OFFSET,0.05); - set_parameter(PARAM_SHADOW_Z_SLOPE_SCALE,0); - set_parameter(PARAM_SHADOW_ESM_MULTIPLIER,60); - set_parameter(PARAM_SHADOW_BLUR_PASSES,1); - - - set_color( COLOR_DIFFUSE, Color(1,1,1)); - set_color( COLOR_SPECULAR, Color(1,1,1)); - - op=OPERATOR_ADD; - set_project_shadows( false ); - set_base(light); - enabled=true; editor_only=false; - bake_mode=BAKE_MODE_DISABLED; + set_color(Color(1,1,1,1)); + set_shadow(false); + set_negative(false); + set_cull_mask(0xFFFFFFFF); + + set_param(PARAM_ENERGY,1); + set_param(PARAM_SPECULAR,0.5); + set_param(PARAM_RANGE,5); + set_param(PARAM_ATTENUATION,1); + set_param(PARAM_SPOT_ANGLE,45); + set_param(PARAM_SPOT_ATTENUATION,1); + set_param(PARAM_SHADOW_MAX_DISTANCE,0); + set_param(PARAM_SHADOW_SPLIT_1_OFFSET,0.1); + set_param(PARAM_SHADOW_SPLIT_2_OFFSET,0.2); + set_param(PARAM_SHADOW_SPLIT_3_OFFSET,0.5); + set_param(PARAM_SHADOW_NORMAL_BIAS,0.1); + set_param(PARAM_SHADOW_BIAS,0.1); + set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE,0.1); } @@ -596,83 +313,116 @@ Light::Light() { Light::~Light() { + VS::get_singleton()->instance_set_base(get_instance(),RID()); + if (light.is_valid()) VisualServer::get_singleton()->free(light); } ///////////////////////////////////////// - void DirectionalLight::set_shadow_mode(ShadowMode p_mode) { shadow_mode=p_mode; - VS::get_singleton()->light_directional_set_shadow_mode(light,(VS::LightDirectionalShadowMode)p_mode); - + VS::get_singleton()->light_directional_set_shadow_mode(light,VS::LightDirectionalShadowMode(p_mode)); } -DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const{ +DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const { return shadow_mode; } -void DirectionalLight::set_shadow_param(ShadowParam p_param, float p_value) { +void DirectionalLight::set_blend_splits(bool p_enable) { - ERR_FAIL_INDEX(p_param,3); - shadow_param[p_param]=p_value; - VS::get_singleton()->light_directional_set_shadow_param(light,VS::LightDirectionalShadowParam(p_param),p_value); + blend_splits=p_enable; + VS::get_singleton()->light_directional_set_blend_splits(light,p_enable); } -float DirectionalLight::get_shadow_param(ShadowParam p_param) const { - ERR_FAIL_INDEX_V(p_param,3,0); - return shadow_param[p_param]; +bool DirectionalLight::is_blend_splits_enabled() const { + + return blend_splits; } + void DirectionalLight::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_shadow_mode","mode"),&DirectionalLight::set_shadow_mode); - ObjectTypeDB::bind_method(_MD("get_shadow_mode"),&DirectionalLight::get_shadow_mode); - ObjectTypeDB::bind_method(_MD("set_shadow_param","param","value"),&DirectionalLight::set_shadow_param); - ObjectTypeDB::bind_method(_MD("get_shadow_param","param"),&DirectionalLight::get_shadow_param); + ObjectTypeDB::bind_method( _MD("set_shadow_mode","mode"),&DirectionalLight::set_shadow_mode); + ObjectTypeDB::bind_method( _MD("get_shadow_mode"),&DirectionalLight::get_shadow_mode); - ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,Perspective,PSSM 2 Splits,PSSM 4 Splits"),_SCS("set_shadow_mode"),_SCS("get_shadow_mode")); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/max_distance",PROPERTY_HINT_EXP_RANGE,"0.00,99999,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_MAX_DISTANCE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/split_weight",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_SPLIT_WEIGHT); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/zoffset_scale",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_ZOFFSET_SCALE); + ObjectTypeDB::bind_method( _MD("set_blend_splits","enabled"),&DirectionalLight::set_blend_splits); + ObjectTypeDB::bind_method( _MD("is_blend_splits_enabled"),&DirectionalLight::is_blend_splits_enabled); + + ADD_PROPERTY( PropertyInfo( Variant::INT, "directional_shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,PSSM 2 Splits,PSSM 4 Splits"), _SCS("set_shadow_mode"), _SCS("get_shadow_mode")); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/split_1",PROPERTY_HINT_RANGE,"0,1,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_1_OFFSET); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/split_2",PROPERTY_HINT_RANGE,"0,1,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_2_OFFSET); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/split_3",PROPERTY_HINT_RANGE,"0,1,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_3_OFFSET); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "directional_shadow/blend_splits"), _SCS("set_blend_splits"), _SCS("is_blend_splits_enabled")); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/normal_bias",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_NORMAL_BIAS); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/bias_split_scale",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS_SPLIT_SCALE); BIND_CONSTANT( SHADOW_ORTHOGONAL ); - BIND_CONSTANT( SHADOW_PERSPECTIVE ); BIND_CONSTANT( SHADOW_PARALLEL_2_SPLITS ); BIND_CONSTANT( SHADOW_PARALLEL_4_SPLITS ); - BIND_CONSTANT( SHADOW_PARAM_MAX_DISTANCE ); - BIND_CONSTANT( SHADOW_PARAM_PSSM_SPLIT_WEIGHT ); - BIND_CONSTANT( SHADOW_PARAM_PSSM_ZOFFSET_SCALE ); } DirectionalLight::DirectionalLight() : Light( VisualServer::LIGHT_DIRECTIONAL ) { - shadow_mode=SHADOW_ORTHOGONAL; - shadow_param[SHADOW_PARAM_MAX_DISTANCE]=0; - shadow_param[SHADOW_PARAM_PSSM_SPLIT_WEIGHT]=0.5; - shadow_param[SHADOW_PARAM_PSSM_ZOFFSET_SCALE]=2.0; + set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); + blend_splits=false; +} +void OmniLight::set_shadow_mode(ShadowMode p_mode) { + shadow_mode=p_mode; + VS::get_singleton()->light_omni_set_shadow_mode(light,VS::LightOmniShadowMode(p_mode)); } +OmniLight::ShadowMode OmniLight::get_shadow_mode() const{ + + return shadow_mode; +} + +void OmniLight::set_shadow_detail(ShadowDetail p_detail){ + + shadow_detail=p_detail; + VS::get_singleton()->light_omni_set_shadow_detail(light,VS::LightOmniShadowDetail(p_detail)); +} +OmniLight::ShadowDetail OmniLight::get_shadow_detail() const{ + + return shadow_detail; +} + + + void OmniLight::_bind_methods() { - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/radius", PROPERTY_HINT_EXP_RANGE, "0.2,4096,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_RADIUS ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION ); + ObjectTypeDB::bind_method( _MD("set_shadow_mode","mode"),&OmniLight::set_shadow_mode); + ObjectTypeDB::bind_method( _MD("get_shadow_mode"),&OmniLight::get_shadow_mode); + + ObjectTypeDB::bind_method( _MD("set_shadow_detail","detail"),&OmniLight::set_shadow_detail); + ObjectTypeDB::bind_method( _MD("get_shadow_detail"),&OmniLight::get_shadow_detail); + + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/range",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/attenuation",PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION); + ADD_PROPERTY( PropertyInfo( Variant::INT, "omni/shadow_mode",PROPERTY_HINT_ENUM,"Dual Paraboloid,Cube"), _SCS("set_shadow_mode"), _SCS("get_shadow_mode")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "omni/shadow_detail",PROPERTY_HINT_ENUM,"Vertical,Horizontal"), _SCS("set_shadow_detail"), _SCS("get_shadow_detail")); } -void SpotLight::_bind_methods() { +OmniLight::OmniLight() : Light( VisualServer::LIGHT_OMNI ) { + + set_shadow_mode(SHADOW_DUAL_PARABOLOID); + set_shadow_detail(SHADOW_DETAIL_HORIZONTAL); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/radius", PROPERTY_HINT_EXP_RANGE, "0.2,4096,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_RADIUS ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION ); +} + +void SpotLight::_bind_methods() { - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_angle", PROPERTY_HINT_RANGE, "0.01,89.9,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ANGLE ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_EXP_EASING, "spot_attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ATTENUATION ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/range",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/attenuation",PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_angle",PROPERTY_HINT_RANGE,"0,180,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ANGLE); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_attenuation",PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ATTENUATION); } diff --git a/scene/3d/light.h b/scene/3d/light.h index 43ac7be350..6818e4f014 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -37,6 +37,10 @@ /** @author Juan Linietsky <reduzio@gmail.com> */ + + +class BakedLight; + class Light : public VisualInstance { OBJ_TYPE( Light, VisualInstance ); @@ -44,58 +48,36 @@ class Light : public VisualInstance { public: - enum Parameter { - PARAM_RADIUS=VisualServer::LIGHT_PARAM_RADIUS, - PARAM_ENERGY=VisualServer::LIGHT_PARAM_ENERGY, - PARAM_ATTENUATION=VisualServer::LIGHT_PARAM_ATTENUATION, - PARAM_SPOT_ANGLE=VisualServer::LIGHT_PARAM_SPOT_ANGLE, - PARAM_SPOT_ATTENUATION=VisualServer::LIGHT_PARAM_SPOT_ATTENUATION, - PARAM_SHADOW_DARKENING=VisualServer::LIGHT_PARAM_SHADOW_DARKENING, - PARAM_SHADOW_Z_OFFSET=VisualServer::LIGHT_PARAM_SHADOW_Z_OFFSET, - PARAM_SHADOW_Z_SLOPE_SCALE=VisualServer::LIGHT_PARAM_SHADOW_Z_SLOPE_SCALE, - PARAM_SHADOW_ESM_MULTIPLIER=VisualServer::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER, - PARAM_SHADOW_BLUR_PASSES=VisualServer::LIGHT_PARAM_SHADOW_BLUR_PASSES, - PARAM_MAX=VisualServer::LIGHT_PARAM_MAX - }; - - - enum LightColor { - - COLOR_DIFFUSE=VisualServer::LIGHT_COLOR_DIFFUSE, - COLOR_SPECULAR=VisualServer::LIGHT_COLOR_SPECULAR - }; - - enum BakeMode { - - BAKE_MODE_DISABLED, - BAKE_MODE_INDIRECT, - BAKE_MODE_INDIRECT_AND_SHADOWS, - BAKE_MODE_FULL - + enum Param { + PARAM_ENERGY = VS::LIGHT_PARAM_ENERGY, + PARAM_SPECULAR = VS::LIGHT_PARAM_SPECULAR, + PARAM_RANGE = VS::LIGHT_PARAM_RANGE, + PARAM_ATTENUATION = VS::LIGHT_PARAM_ATTENUATION, + PARAM_SPOT_ANGLE = VS::LIGHT_PARAM_SPOT_ANGLE, + PARAM_SPOT_ATTENUATION = VS::LIGHT_PARAM_SPOT_ATTENUATION, + PARAM_SHADOW_MAX_DISTANCE = VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE, + PARAM_SHADOW_SPLIT_1_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET, + PARAM_SHADOW_SPLIT_2_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET, + PARAM_SHADOW_SPLIT_3_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET, + PARAM_SHADOW_NORMAL_BIAS = VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS, + PARAM_SHADOW_BIAS = VS::LIGHT_PARAM_SHADOW_BIAS, + PARAM_SHADOW_BIAS_SPLIT_SCALE = VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE, + PARAM_MAX = VS::LIGHT_PARAM_MAX }; - - enum Operator { - - OPERATOR_ADD, - OPERATOR_SUB - }; private: - - Ref<Texture> projector; - float vars[PARAM_MAX]; - Color colors[3]; - - - BakeMode bake_mode; - VisualServer::LightType type; - bool shadows; - bool enabled; + Color color; + float param[PARAM_MAX]; + Color shadow_color; + bool shadow; + bool negative; + uint32_t cull_mask; + VS::LightType type; bool editor_only; - Operator op; - void _update_visibility(); + + BakedLight *baked_light; // bind helpers protected: @@ -103,8 +85,7 @@ protected: RID light; virtual bool _can_gizmo_scale() const; - virtual RES _get_gizmo_geometry() const; - + static void _bind_methods(); void _notification(int p_what); @@ -114,44 +95,37 @@ public: VS::LightType get_light_type() const { return type; } - void set_parameter(Parameter p_var, float p_value); - float get_parameter(Parameter p_var) const; + void set_editor_only(bool p_editor_only); + bool is_editor_only() const; - void set_color(LightColor p_color,const Color& p_value); - Color get_color(LightColor p_color) const; + void set_param(Param p_param, float p_value); + float get_param(Param p_param) const; - void set_project_shadows(bool p_enabled); - bool has_project_shadows() const; + void set_shadow(bool p_enable); + bool has_shadow() const; - void set_projector(const Ref<Texture>& p_projector); - Ref<Texture> get_projector() const; + void set_negative(bool p_enable); + bool is_negative() const; - void set_operator(Operator p_op); - Operator get_operator() const; + void set_cull_mask(uint32_t p_cull_mask); + uint32_t get_cull_mask() const; - void set_bake_mode(BakeMode p_bake_mode); - BakeMode get_bake_mode() const; + void set_color(const Color& p_color); + Color get_color() const; - void set_enabled(bool p_enabled); - bool is_enabled() const; + void set_shadow_color(const Color& p_shadow_color); + Color get_shadow_color() const; - void set_editor_only(bool p_editor_only); - bool is_editor_only() const; virtual AABB get_aabb() const; virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const; - void approximate_opengl_attenuation(float p_constant, float p_linear, float p_quadratic, float p_radius_treshold=0.5); - Light(); ~Light(); }; -VARIANT_ENUM_CAST( Light::Parameter ); -VARIANT_ENUM_CAST( Light::LightColor ); -VARIANT_ENUM_CAST( Light::Operator ); -VARIANT_ENUM_CAST( Light::BakeMode); +VARIANT_ENUM_CAST(Light::Param); class DirectionalLight : public Light { @@ -162,19 +136,15 @@ public: enum ShadowMode { SHADOW_ORTHOGONAL, - SHADOW_PERSPECTIVE, SHADOW_PARALLEL_2_SPLITS, SHADOW_PARALLEL_4_SPLITS }; - enum ShadowParam { - SHADOW_PARAM_MAX_DISTANCE, - SHADOW_PARAM_PSSM_SPLIT_WEIGHT, - SHADOW_PARAM_PSSM_ZOFFSET_SCALE - }; private: + + bool blend_splits; ShadowMode shadow_mode; - float shadow_param[3]; + protected: static void _bind_methods(); public: @@ -182,30 +152,51 @@ public: void set_shadow_mode(ShadowMode p_mode); ShadowMode get_shadow_mode() const; - void set_shadow_max_distance(float p_distance); - float get_shadow_max_distance() const; - void set_shadow_param(ShadowParam p_param, float p_value); - float get_shadow_param(ShadowParam p_param) const; + void set_blend_splits(bool p_enable); + bool is_blend_splits_enabled() const; DirectionalLight(); }; -VARIANT_ENUM_CAST( DirectionalLight::ShadowMode ); -VARIANT_ENUM_CAST( DirectionalLight::ShadowParam ); - +VARIANT_ENUM_CAST(DirectionalLight::ShadowMode) class OmniLight : public Light { OBJ_TYPE( OmniLight, Light ); +public: + // omni light + enum ShadowMode { + SHADOW_DUAL_PARABOLOID, + SHADOW_CUBE, + }; + + // omni light + enum ShadowDetail { + SHADOW_DETAIL_VERTICAL, + SHADOW_DETAIL_HORIZONTAL + }; + +private: + + ShadowMode shadow_mode; + ShadowDetail shadow_detail; protected: static void _bind_methods(); public: + void set_shadow_mode(ShadowMode p_mode); + ShadowMode get_shadow_mode() const; - OmniLight() : Light( VisualServer::LIGHT_OMNI ) { set_parameter(PARAM_SHADOW_Z_OFFSET,0.001);} + void set_shadow_detail(ShadowDetail p_detail); + ShadowDetail get_shadow_detail() const; + + OmniLight(); }; +VARIANT_ENUM_CAST(OmniLight::ShadowMode) +VARIANT_ENUM_CAST(OmniLight::ShadowDetail) + class SpotLight : public Light { OBJ_TYPE( SpotLight, Light ); diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp index 25f675ac0c..dfa8e5901f 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -201,7 +201,7 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { arr.resize(Mesh::ARRAY_MAX); arr[Mesh::ARRAY_VERTEX]=varr; - debug_mesh->add_surface(Mesh::PRIMITIVE_LINES,arr); + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES,arr); return debug_mesh; } diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index c700fed575..289dec534b 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -30,6 +30,7 @@ #include "servers/visual_server.h" #include "scene/resources/surface_tool.h" +#if 0 /* static const char* _var_names[Particles::VAR_MAX]={ "vars/lifetime", @@ -318,10 +319,10 @@ RES Particles::_get_gizmo_geometry() const { Ref<SurfaceTool> surface_tool( memnew( SurfaceTool )); - Ref<FixedMaterial> mat( memnew( FixedMaterial )); + Ref<FixedSpatialMaterial> mat( memnew( FixedSpatialMaterial )); - mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.2) ); - mat->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) ); + mat->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.2) ); + mat->set_parameter( FixedSpatialMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) ); mat->set_blend_mode( Material::BLEND_MODE_ADD ); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); // mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); @@ -381,9 +382,9 @@ RES Particles::_get_gizmo_geometry() const { Ref<Mesh> mesh = surface_tool->commit(); - Ref<FixedMaterial> mat_aabb( memnew( FixedMaterial )); + Ref<FixedSpatialMaterial> mat_aabb( memnew( FixedSpatialMaterial )); - mat_aabb->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.9,0.7) ); + mat_aabb->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.9,0.7) ); mat_aabb->set_line_width(3); mat_aabb->set_flag( Material::FLAG_UNSHADED, true ); @@ -557,3 +558,4 @@ Particles::~Particles() { VisualServer::get_singleton()->free(particles); } +#endif diff --git a/scene/3d/particles.h b/scene/3d/particles.h index 21e975138c..7b42f5f26a 100644 --- a/scene/3d/particles.h +++ b/scene/3d/particles.h @@ -37,7 +37,7 @@ /** @author Juan Linietsky <reduzio@gmail.com> */ - +#if 0 class Particles : public GeometryInstance { public: @@ -163,3 +163,4 @@ public: VARIANT_ENUM_CAST( Particles::Variable ); #endif +#endif diff --git a/scene/3d/portal.cpp b/scene/3d/portal.cpp index 0630e6a1de..421cfcc787 100644 --- a/scene/3d/portal.cpp +++ b/scene/3d/portal.cpp @@ -96,45 +96,6 @@ void Portal::_get_property_list( List<PropertyInfo> *p_list) const { } -RES Portal::_get_gizmo_geometry() const { - - Ref<SurfaceTool> surface_tool( memnew( SurfaceTool )); - - Ref<FixedMaterial> mat( memnew( FixedMaterial )); - - mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.8,0.8,0.7) ); - mat->set_line_width(4); - mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); - mat->set_flag(Material::FLAG_UNSHADED,true); -// mat->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER,true); - - surface_tool->begin(Mesh::PRIMITIVE_LINES); - surface_tool->set_material(mat); - - Vector<Point2> shape = get_shape(); - - Vector2 center; - for (int i=0;i<shape.size();i++) { - - int n=(i+1)%shape.size(); - Vector<Vector3> points; - surface_tool->add_vertex( Vector3( shape[i].x, shape[i].y,0 )); - surface_tool->add_vertex( Vector3( shape[n].x, shape[n].y,0 )); - center+=shape[i]; - - } - - if (shape.size()>0) { - - center/=shape.size(); - Vector<Vector3> points; - surface_tool->add_vertex( Vector3( center.x, center.y,0 )); - surface_tool->add_vertex( Vector3( center.x, center.y,1.0 )); - } - - return surface_tool->commit(); -} - AABB Portal::get_aabb() const { @@ -178,18 +139,19 @@ void Portal::set_shape(const Vector<Point2>& p_shape) { VisualServer::get_singleton()->portal_set_shape(portal, p_shape); + shape=p_shape; update_gizmo(); } Vector<Point2> Portal::get_shape() const { - return VisualServer::get_singleton()->portal_get_shape(portal); + return shape; } void Portal::set_connect_range(float p_range) { connect_range=p_range; - VisualServer::get_singleton()->portal_set_connect_range(portal,p_range); + //VisualServer::get_singleton()->portal_set_connect_range(portal,p_range); } float Portal::get_connect_range() const { diff --git a/scene/3d/portal.h b/scene/3d/portal.h index 9443ffca99..e69e973146 100644 --- a/scene/3d/portal.h +++ b/scene/3d/portal.h @@ -47,6 +47,7 @@ class Portal : public VisualInstance { OBJ_TYPE(Portal, VisualInstance); RID portal; + Vector<Point2> shape; bool enabled; float disable_distance; @@ -55,7 +56,6 @@ class Portal : public VisualInstance { AABB aabb; - virtual RES _get_gizmo_geometry() const; protected: diff --git a/scene/3d/position_3d.cpp b/scene/3d/position_3d.cpp index c08d2609b1..e7403053b2 100644 --- a/scene/3d/position_3d.cpp +++ b/scene/3d/position_3d.cpp @@ -29,37 +29,6 @@ #include "position_3d.h" #include "scene/resources/mesh.h" -RES Position3D::_get_gizmo_geometry() const { - - - Ref<Mesh> mesh = memnew( Mesh ); - - DVector<Vector3> cursor_points; - DVector<Color> cursor_colors; - float cs = 0.25; - cursor_points.push_back(Vector3(+cs,0,0)); - cursor_points.push_back(Vector3(-cs,0,0)); - cursor_points.push_back(Vector3(0,+cs,0)); - cursor_points.push_back(Vector3(0,-cs,0)); - cursor_points.push_back(Vector3(0,0,+cs)); - cursor_points.push_back(Vector3(0,0,-cs)); - cursor_colors.push_back(Color(1,0.5,0.5,1)); - cursor_colors.push_back(Color(1,0.5,0.5,1)); - cursor_colors.push_back(Color(0.5,1,0.5,1)); - cursor_colors.push_back(Color(0.5,1,0.5,1)); - cursor_colors.push_back(Color(0.5,0.5,1,1)); - cursor_colors.push_back(Color(0.5,0.5,1,1)); - - Ref<FixedMaterial> mat = memnew( FixedMaterial ); - mat->set_flag(Material::FLAG_UNSHADED,true); - mat->set_line_width(3); - Array d; - d[Mesh::ARRAY_VERTEX]=cursor_points; - d[Mesh::ARRAY_COLOR]=cursor_colors; - mesh->add_surface(Mesh::PRIMITIVE_LINES,d); - mesh->surface_set_material(0,mat); - return mesh; -} Position3D::Position3D() { diff --git a/scene/3d/position_3d.h b/scene/3d/position_3d.h index 1c2afe9ee6..47f71845f0 100644 --- a/scene/3d/position_3d.h +++ b/scene/3d/position_3d.h @@ -35,7 +35,6 @@ class Position3D : public Spatial { OBJ_TYPE(Position3D,Spatial); - virtual RES _get_gizmo_geometry() const; public: diff --git a/scene/3d/quad.cpp b/scene/3d/quad.cpp index 519757ba04..2d433fbb8c 100644 --- a/scene/3d/quad.cpp +++ b/scene/3d/quad.cpp @@ -120,7 +120,7 @@ void Quad::_update() { } else { configured=true; } - VS::get_singleton()->mesh_add_surface(mesh,VS::PRIMITIVE_TRIANGLES,arr); + VS::get_singleton()->mesh_add_surface_from_arrays(mesh,VS::PRIMITIVE_TRIANGLES,arr); pending_update=false; } diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp new file mode 100644 index 0000000000..09082b0f28 --- /dev/null +++ b/scene/3d/reflection_probe.cpp @@ -0,0 +1,266 @@ +#include "reflection_probe.h" + + +void ReflectionProbe::set_intensity(float p_intensity) { + + intensity=p_intensity; + VS::get_singleton()->reflection_probe_set_intensity(probe,p_intensity); +} + +float ReflectionProbe::get_intensity() const{ + + return intensity; +} + + +void ReflectionProbe::set_interior_ambient(Color p_ambient) { + + interior_ambient=p_ambient; + VS::get_singleton()->reflection_probe_set_interior_ambient(probe,p_ambient); +} + +void ReflectionProbe::set_interior_ambient_energy(float p_energy) { + interior_ambient_energy=p_energy; + VS::get_singleton()->reflection_probe_set_interior_ambient_energy(probe,p_energy); +} + +float ReflectionProbe::get_interior_ambient_energy() const{ + return interior_ambient_energy; +} + + +Color ReflectionProbe::get_interior_ambient() const{ + + return interior_ambient; +} + +void ReflectionProbe::set_interior_ambient_probe_contribution(float p_contribution) { + + interior_ambient_probe_contribution=p_contribution; + VS::get_singleton()->reflection_probe_set_interior_ambient_probe_contribution(probe,p_contribution); +} + +float ReflectionProbe::get_interior_ambient_probe_contribution() const{ + + return interior_ambient_probe_contribution; +} + + +void ReflectionProbe::set_max_distance(float p_distance){ + + max_distance=p_distance; + VS::get_singleton()->reflection_probe_set_max_distance(probe,p_distance); +} +float ReflectionProbe::get_max_distance() const{ + + return max_distance; +} + + +void ReflectionProbe::set_extents(const Vector3& p_extents){ + + extents=p_extents; + + for(int i=0;i<3;i++) { + if (extents[i]<0.01) { + extents[i]=0.01; + } + + if (extents[i]-0.01<ABS(origin_offset[i])) { + origin_offset[i]=SGN(origin_offset[i])*(extents[i]-0.01); + _change_notify("origin_offset"); + } + } + + VS::get_singleton()->reflection_probe_set_extents(probe,extents); + VS::get_singleton()->reflection_probe_set_origin_offset(probe,origin_offset); + _change_notify("extents"); + update_gizmo(); + +} +Vector3 ReflectionProbe::get_extents() const{ + + return extents; +} + +void ReflectionProbe::set_origin_offset(const Vector3& p_extents){ + + origin_offset=p_extents; + + for(int i=0;i<3;i++) { + + if (extents[i]-0.01<ABS(origin_offset[i])) { + origin_offset[i]=SGN(origin_offset[i])*(extents[i]-0.01); + + } + } + VS::get_singleton()->reflection_probe_set_extents(probe,extents); + VS::get_singleton()->reflection_probe_set_origin_offset(probe,origin_offset); + + _change_notify("origin_offset"); + update_gizmo(); +} +Vector3 ReflectionProbe::get_origin_offset() const{ + + return origin_offset; +} + +void ReflectionProbe::set_enable_box_projection(bool p_enable){ + + box_projection=p_enable; + VS::get_singleton()->reflection_probe_set_enable_box_projection(probe,p_enable); + +} +bool ReflectionProbe::is_box_projection_enabled() const{ + + return box_projection; +} + + +void ReflectionProbe::set_as_interior(bool p_enable) { + + interior=p_enable; + VS::get_singleton()->reflection_probe_set_as_interior(probe,interior); + _change_notify(); + +} + +bool ReflectionProbe::is_set_as_interior() const { + + return interior; +} + + + +void ReflectionProbe::set_enable_shadows(bool p_enable) { + + enable_shadows=p_enable; + VS::get_singleton()->reflection_probe_set_enable_shadows(probe,p_enable); +} +bool ReflectionProbe::are_shadows_enabled() const { + + return enable_shadows; +} + +void ReflectionProbe::set_cull_mask(uint32_t p_layers) { + + cull_mask=p_layers; + VS::get_singleton()->reflection_probe_set_enable_shadows(probe,p_layers); +} +uint32_t ReflectionProbe::get_cull_mask() const { + + return cull_mask; +} + +void ReflectionProbe::set_update_mode(UpdateMode p_mode) { + update_mode=p_mode; + VS::get_singleton()->reflection_probe_set_update_mode(probe,VS::ReflectionProbeUpdateMode(p_mode)); +} + +ReflectionProbe::UpdateMode ReflectionProbe::get_update_mode() const { + return update_mode; +} + + +AABB ReflectionProbe::get_aabb() const { + + AABB aabb; + aabb.pos=-origin_offset; + aabb.size=origin_offset+extents; + return aabb; +} +DVector<Face3> ReflectionProbe::get_faces(uint32_t p_usage_flags) const { + + return DVector<Face3>(); +} + +void ReflectionProbe::_validate_property(PropertyInfo& property) const { + + if (property.name=="interior/ambient_color" || property.name=="interior/ambient_energy" || property.name=="interior/ambient_contrib") { + if (!interior) { + property.usage=PROPERTY_USAGE_NOEDITOR; + } + } +} + +void ReflectionProbe::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_intensity","intensity"),&ReflectionProbe::set_intensity); + ObjectTypeDB::bind_method(_MD("get_intensity"),&ReflectionProbe::get_intensity); + + ObjectTypeDB::bind_method(_MD("set_interior_ambient","ambient"),&ReflectionProbe::set_interior_ambient); + ObjectTypeDB::bind_method(_MD("get_interior_ambient"),&ReflectionProbe::get_interior_ambient); + + ObjectTypeDB::bind_method(_MD("set_interior_ambient_energy","ambient_energy"),&ReflectionProbe::set_interior_ambient_energy); + ObjectTypeDB::bind_method(_MD("get_interior_ambient_energy"),&ReflectionProbe::get_interior_ambient_energy); + + ObjectTypeDB::bind_method(_MD("set_interior_ambient_probe_contribution","ambient_probe_contribution"),&ReflectionProbe::set_interior_ambient_probe_contribution); + ObjectTypeDB::bind_method(_MD("get_interior_ambient_probe_contribution"),&ReflectionProbe::get_interior_ambient_probe_contribution); + + ObjectTypeDB::bind_method(_MD("set_max_distance","max_distance"),&ReflectionProbe::set_max_distance); + ObjectTypeDB::bind_method(_MD("get_max_distance"),&ReflectionProbe::get_max_distance); + + ObjectTypeDB::bind_method(_MD("set_extents","extents"),&ReflectionProbe::set_extents); + ObjectTypeDB::bind_method(_MD("get_extents"),&ReflectionProbe::get_extents); + + ObjectTypeDB::bind_method(_MD("set_origin_offset","origin_offset"),&ReflectionProbe::set_origin_offset); + ObjectTypeDB::bind_method(_MD("get_origin_offset"),&ReflectionProbe::get_origin_offset); + + ObjectTypeDB::bind_method(_MD("set_as_interior","enable"),&ReflectionProbe::set_as_interior); + ObjectTypeDB::bind_method(_MD("is_set_as_interior"),&ReflectionProbe::is_set_as_interior); + + ObjectTypeDB::bind_method(_MD("set_enable_box_projection","enable"),&ReflectionProbe::set_enable_box_projection); + ObjectTypeDB::bind_method(_MD("is_box_projection_enabled"),&ReflectionProbe::is_box_projection_enabled); + + + ObjectTypeDB::bind_method(_MD("set_enable_shadows","enable"),&ReflectionProbe::set_enable_shadows); + ObjectTypeDB::bind_method(_MD("are_shadows_enabled"),&ReflectionProbe::are_shadows_enabled); + + ObjectTypeDB::bind_method(_MD("set_cull_mask","layers"),&ReflectionProbe::set_cull_mask); + ObjectTypeDB::bind_method(_MD("get_cull_mask"),&ReflectionProbe::get_cull_mask); + + ObjectTypeDB::bind_method(_MD("set_update_mode","mode"),&ReflectionProbe::set_update_mode); + ObjectTypeDB::bind_method(_MD("get_update_mode"),&ReflectionProbe::get_update_mode); + + ADD_PROPERTY( PropertyInfo(Variant::INT,"update_mode",PROPERTY_HINT_ENUM,"Once,Always"),_SCS("set_update_mode"),_SCS("get_update_mode")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"intensity",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_intensity"),_SCS("get_intensity")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"max_distance",PROPERTY_HINT_RANGE,"0,16384,0.1"),_SCS("set_max_distance"),_SCS("get_max_distance")); + ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"extents"),_SCS("set_extents"),_SCS("get_extents")); + ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"origin_offset"),_SCS("set_origin_offset"),_SCS("get_origin_offset")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"box_projection"),_SCS("set_enable_box_projection"),_SCS("is_box_projection_enabled")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enable_shadows"),_SCS("set_enable_shadows"),_SCS("are_shadows_enabled")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cull_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_cull_mask"),_SCS("get_cull_mask")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"interior/enable"),_SCS("set_as_interior"),_SCS("is_set_as_interior")); + ADD_PROPERTY( PropertyInfo(Variant::COLOR,"interior/ambient_color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("set_interior_ambient"),_SCS("get_interior_ambient")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"interior/ambient_energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_interior_ambient_energy"),_SCS("get_interior_ambient_energy")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"interior/ambient_contrib",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_interior_ambient_probe_contribution"),_SCS("get_interior_ambient_probe_contribution")); + + + BIND_CONSTANT( UPDATE_ONCE ); + BIND_CONSTANT( UPDATE_ALWAYS ); + +} + +ReflectionProbe::ReflectionProbe() { + + intensity=1.0; + interior_ambient=Color(0,0,0); + interior_ambient_probe_contribution=0; + interior_ambient_energy=1.0; + max_distance=0; + extents=Vector3(1,1,1); + origin_offset=Vector3(0,0,0); + box_projection=false; + interior=false; + enable_shadows=false; + cull_mask=(1<<20)-1; + update_mode=UPDATE_ONCE; + + probe=VisualServer::get_singleton()->reflection_probe_create(); + VS::get_singleton()->instance_set_base(get_instance(),probe); +} + +ReflectionProbe::~ReflectionProbe() { + + VS::get_singleton()->free(probe); +} diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h new file mode 100644 index 0000000000..5ea41a91c9 --- /dev/null +++ b/scene/3d/reflection_probe.h @@ -0,0 +1,92 @@ +#ifndef REFLECTIONPROBE_H +#define REFLECTIONPROBE_H + +#include "scene/3d/visual_instance.h" +#include "scene/resources/texture.h" +#include "scene/resources/sky_box.h" +#include "servers/visual_server.h" + +class ReflectionProbe : public VisualInstance { + OBJ_TYPE(ReflectionProbe,VisualInstance); + +public: + + enum UpdateMode { + UPDATE_ONCE, + UPDATE_ALWAYS, + }; + + +private: + + RID probe; + float intensity; + float max_distance; + Vector3 extents; + Vector3 origin_offset; + bool box_projection; + bool enable_shadows; + bool interior; + Color interior_ambient; + float interior_ambient_energy; + float interior_ambient_probe_contribution; + + uint32_t cull_mask; + UpdateMode update_mode; + +protected: + + static void _bind_methods(); + void _validate_property(PropertyInfo& property) const; + +public: + + void set_intensity(float p_intensity); + float get_intensity() const; + + void set_interior_ambient(Color p_ambient); + Color get_interior_ambient() const; + + void set_interior_ambient_energy(float p_energy); + float get_interior_ambient_energy() const; + + void set_interior_ambient_probe_contribution(float p_contribution); + float get_interior_ambient_probe_contribution() const; + + void set_max_distance(float p_distance); + float get_max_distance() const; + + void set_extents(const Vector3& p_extents); + Vector3 get_extents() const; + + void set_origin_offset(const Vector3& p_extents); + Vector3 get_origin_offset() const; + + void set_as_interior(bool p_enable); + bool is_set_as_interior() const; + + void set_enable_box_projection(bool p_enable); + bool is_box_projection_enabled() const; + + void set_enable_shadows(bool p_enable); + bool are_shadows_enabled() const; + + void set_cull_mask(uint32_t p_layers); + uint32_t get_cull_mask() const; + + void set_update_mode(UpdateMode p_mode); + UpdateMode get_update_mode() const; + + virtual AABB get_aabb() const; + virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const; + + + + ReflectionProbe(); + ~ReflectionProbe(); +}; + + +VARIANT_ENUM_CAST( ReflectionProbe::UpdateMode ); + +#endif // REFLECTIONPROBE_H diff --git a/scene/3d/room_instance.cpp b/scene/3d/room_instance.cpp index 3b4eb0b522..ea3200622e 100644 --- a/scene/3d/room_instance.cpp +++ b/scene/3d/room_instance.cpp @@ -75,50 +75,6 @@ void Room::_notification(int p_what) { } -RES Room::_get_gizmo_geometry() const { - - DVector<Face3> faces; - if (!room.is_null()) - faces=room->get_geometry_hint(); - - int count=faces.size(); - if (count==0) - return RES(); - - DVector<Face3>::Read facesr=faces.read(); - - const Face3* facesptr=facesr.ptr(); - - DVector<Vector3> points; - - Ref<SurfaceTool> surface_tool( memnew( SurfaceTool )); - - Ref<FixedMaterial> mat( memnew( FixedMaterial )); - - mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.2,0.8,0.9,0.3) ); - mat->set_line_width(4); - mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); - mat->set_flag(Material::FLAG_UNSHADED,true); -// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); - - surface_tool->begin(Mesh::PRIMITIVE_LINES); - surface_tool->set_material(mat); - - for (int i=0;i<count;i++) { - - surface_tool->add_vertex(facesptr[i].vertex[0]); - surface_tool->add_vertex(facesptr[i].vertex[1]); - - surface_tool->add_vertex(facesptr[i].vertex[1]); - surface_tool->add_vertex(facesptr[i].vertex[2]); - - surface_tool->add_vertex(facesptr[i].vertex[2]); - surface_tool->add_vertex(facesptr[i].vertex[0]); - - } - - return surface_tool->commit(); -} @@ -127,8 +83,9 @@ AABB Room::get_aabb() const { if (room.is_null()) return AABB(); - return room->get_bounds().get_aabb(); + return AABB(); } + DVector<Face3> Room::get_faces(uint32_t p_usage_flags) const { return DVector<Face3>(); @@ -154,9 +111,6 @@ void Room::set_room( const Ref<RoomBounds>& p_room ) { propagate_notification(NOTIFICATION_AREA_CHANGED); update_gizmo(); - if (room.is_valid()) - SpatialSoundServer::get_singleton()->room_set_bounds(sound_room,room->get_bounds()); - } @@ -202,32 +156,6 @@ void Room::_parse_node_faces(DVector<Face3> &all_faces,const Node *p_node) const } -void Room::compute_room_from_subtree() { - - - DVector<Face3> all_faces; - _parse_node_faces(all_faces,this); - - - if (all_faces.size()==0) - return; - float error; - DVector<Face3> wrapped_faces = Geometry::wrap_geometry(all_faces,&error); - - - if (wrapped_faces.size()==0) - return; - - BSP_Tree tree(wrapped_faces,error); - - Ref<RoomBounds> room( memnew( RoomBounds ) ); - room->set_bounds(tree); - room->set_geometry_hint(wrapped_faces); - - set_room(room); - -} - void Room::set_simulate_acoustics(bool p_enable) { @@ -268,7 +196,6 @@ void Room::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_room","room:Room"),&Room::set_room ); ObjectTypeDB::bind_method(_MD("get_room:Room"),&Room::get_room ); - ObjectTypeDB::bind_method(_MD("compute_room_from_subtree"),&Room::compute_room_from_subtree); diff --git a/scene/3d/room_instance.h b/scene/3d/room_instance.h index d0c7dd1268..b40665b498 100644 --- a/scene/3d/room_instance.h +++ b/scene/3d/room_instance.h @@ -45,6 +45,8 @@ */ + + class Room : public VisualInstance { OBJ_TYPE( Room, VisualInstance ); @@ -65,7 +67,7 @@ private: void _bounds_changed(); - virtual RES _get_gizmo_geometry() const; + protected: @@ -89,7 +91,6 @@ public: void set_simulate_acoustics(bool p_enable); bool is_simulating_acoustics() const; - void compute_room_from_subtree(); RID get_sound_room() const; diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp index 6ca954190f..dfc58dc4c3 100644 --- a/scene/3d/skeleton.cpp +++ b/scene/3d/skeleton.cpp @@ -163,7 +163,7 @@ void Skeleton::_notification(int p_what) { Bone *bonesptr=&bones[0]; int len=bones.size(); - vs->skeleton_resize( skeleton, len ); // if same size, nothin really happens + vs->skeleton_allocate( skeleton, len ); // if same size, nothin really happens // pose changed, rebuild cache of inverses if (rest_global_inverse_dirty) { @@ -513,51 +513,6 @@ void Skeleton::_make_dirty() { } -RES Skeleton::_get_gizmo_geometry() const { - - if (!GLOBAL_DEF("debug/draw_skeleton", true)) - return RES(); - - if (bones.size()==0) - return RES(); - - Ref<SurfaceTool> surface_tool( memnew( SurfaceTool )); - - Ref<FixedMaterial> mat( memnew( FixedMaterial )); - - mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.6,1.0,0.3,0.1) ); - mat->set_line_width(4); - mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); - mat->set_flag(Material::FLAG_UNSHADED,true); - mat->set_flag(Material::FLAG_ONTOP,true); -// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); - - surface_tool->begin(Mesh::PRIMITIVE_LINES); - surface_tool->set_material(mat); - - - const Bone *bonesptr=&bones[0]; - int len=bones.size(); - - for (int i=0;i<len;i++) { - - const Bone &b=bonesptr[i]; - - Transform t; - if (b.parent<0) - continue; - - Vector3 v1=(bonesptr[b.parent].pose_global * bonesptr[b.parent].rest_global_inverse).xform(bonesptr[b.parent].rest_global_inverse.affine_inverse().origin); - Vector3 v2=(b.pose_global * b.rest_global_inverse).xform(b.rest_global_inverse.affine_inverse().origin); - - surface_tool->add_vertex(v1); - surface_tool->add_vertex(v2); - - } - - return surface_tool->commit(); - -} void Skeleton::localize_rests() { diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h index ddecafd12c..37810e5466 100644 --- a/scene/3d/skeleton.h +++ b/scene/3d/skeleton.h @@ -84,7 +84,6 @@ class Skeleton : public Spatial { return bound; } - virtual RES _get_gizmo_geometry() const; protected: diff --git a/scene/3d/spatial_player.cpp b/scene/3d/spatial_player.cpp index 2bd94aac79..017f17226f 100644 --- a/scene/3d/spatial_player.cpp +++ b/scene/3d/spatial_player.cpp @@ -88,146 +88,6 @@ bool SpatialPlayer::_can_gizmo_scale() const { return false; } -RES SpatialPlayer::_get_gizmo_geometry() const { - - Ref<SurfaceTool> surface_tool( memnew( SurfaceTool )); - - Ref<FixedMaterial> mat( memnew( FixedMaterial )); - - mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.05) ); - mat->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) ); - mat->set_blend_mode( Material::BLEND_MODE_ADD ); - mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); -// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); - - - surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES); - surface_tool->set_material(mat); - - int sides=16; - int sections=24; - -// float len=1; - float deg=Math::deg2rad(params[PARAM_EMISSION_CONE_DEGREES]); - if (deg==180) - deg=179.5; - - Vector3 to=Vector3(0,0,-1); - - for(int j=0;j<sections;j++) { - - Vector3 p1=Matrix3(Vector3(1,0,0),deg*j/sections).xform(to); - Vector3 p2=Matrix3(Vector3(1,0,0),deg*(j+1)/sections).xform(to); - - for(int i=0;i<sides;i++) { - - Vector3 p1r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p1); - Vector3 p1s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p1); - Vector3 p2s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p2); - Vector3 p2r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p2); - - surface_tool->add_normal(p1r.normalized()); - surface_tool->add_vertex(p1r); - surface_tool->add_normal(p1s.normalized()); - surface_tool->add_vertex(p1s); - surface_tool->add_normal(p2s.normalized()); - surface_tool->add_vertex(p2s); - - surface_tool->add_normal(p1r.normalized()); - surface_tool->add_vertex(p1r); - surface_tool->add_normal(p2s.normalized()); - surface_tool->add_vertex(p2s); - surface_tool->add_normal(p2r.normalized()); - surface_tool->add_vertex(p2r); - - if (j==sections-1) { - - surface_tool->add_normal(p2r.normalized()); - surface_tool->add_vertex(p2r); - surface_tool->add_normal(p2s.normalized()); - surface_tool->add_vertex(p2s); - surface_tool->add_normal(Vector3(0,0,1)); - surface_tool->add_vertex(Vector3()); - } - } - } - - - Ref<Mesh> mesh = surface_tool->commit(); - - Ref<FixedMaterial> mat_speaker( memnew( FixedMaterial )); - - mat_speaker->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.3,0.3,0.6) ); - mat_speaker->set_parameter( FixedMaterial::PARAM_SPECULAR,Color(0.5,0.5,0.6) ); - //mat_speaker->set_blend_mode( Material::BLEND_MODE_MIX); - //mat_speaker->set_flag(Material::FLAG_DOUBLE_SIDED,false); - //mat_speaker->set_flag(Material::FLAG_UNSHADED,true); - - surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES); - surface_tool->set_material(mat_speaker); - -// float radius=1; - - - const int speaker_points=8; - Vector3 speaker[speaker_points]={ - Vector3(0,0,1)*0.15, - Vector3(1,1,1)*0.15, - Vector3(1,1,0)*0.15, - Vector3(2,2,-1)*0.15, - Vector3(1,1,-1)*0.15, - Vector3(0.8,0.8,-1.2)*0.15, - Vector3(0.5,0.5,-1.4)*0.15, - Vector3(0.0,0.0,-1.6)*0.15 - }; - - int speaker_sides=10; - - - for(int i = 0; i < speaker_sides ; i++) { - - - Matrix3 ma(Vector3(0,0,1),Math_PI*2*float(i)/speaker_sides); - Matrix3 mb(Vector3(0,0,1),Math_PI*2*float(i+1)/speaker_sides); - - - for(int j=0;j<speaker_points-1;j++) { - - Vector3 points[4]={ - ma.xform(speaker[j]), - mb.xform(speaker[j]), - mb.xform(speaker[j+1]), - ma.xform(speaker[j+1]), - }; - - Vector3 n = -Plane(points[0],points[1],points[2]).normal; - - surface_tool->add_normal(n); - surface_tool->add_vertex(points[0]); - surface_tool->add_normal(n); - surface_tool->add_vertex(points[2]); - surface_tool->add_normal(n); - surface_tool->add_vertex(points[1]); - - surface_tool->add_normal(n); - surface_tool->add_vertex(points[0]); - surface_tool->add_normal(n); - surface_tool->add_vertex(points[3]); - surface_tool->add_normal(n); - surface_tool->add_vertex(points[2]); - - - } - - - } - - - return surface_tool->commit(mesh); - -} - - void SpatialPlayer::_bind_methods() { diff --git a/scene/3d/spatial_player.h b/scene/3d/spatial_player.h index 258bf5e411..73a19eee4d 100644 --- a/scene/3d/spatial_player.h +++ b/scene/3d/spatial_player.h @@ -60,7 +60,7 @@ private: RID source_rid; virtual bool _can_gizmo_scale() const; - virtual RES _get_gizmo_geometry() const; + protected: diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index 155fe96ba7..5386680200 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -31,7 +31,6 @@ #include "servers/visual_server.h" #include "room_instance.h" #include "scene/scene_string_names.h" -#include "baked_light_instance.h" #include "skeleton.h" AABB VisualInstance::get_transformed_aabb() const { @@ -52,7 +51,7 @@ void VisualInstance::_notification(int p_what) { Room *room=NULL; bool is_geom = cast_to<GeometryInstance>(); - while(parent) { + /* while(parent) { room = parent->cast_to<Room>(); if (room) @@ -64,7 +63,7 @@ void VisualInstance::_notification(int p_what) { } parent=parent->get_parent_spatial(); - } + }*/ @@ -92,7 +91,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() ); + // VS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() ); } break; @@ -172,89 +171,78 @@ Ref<Material> GeometryInstance::get_material_override() const{ -void GeometryInstance::set_draw_range_begin(float p_dist){ +void GeometryInstance::set_lod_min_distance(float p_dist){ - draw_begin=p_dist; - VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),draw_begin,draw_end); + lod_min_distance=p_dist; + VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),lod_min_distance,lod_max_distance,lod_min_hysteresis,lod_max_hysteresis); } -float GeometryInstance::get_draw_range_begin() const{ +float GeometryInstance::get_lod_min_distance() const{ - return draw_begin; + return lod_min_distance; } -void GeometryInstance::set_draw_range_end(float p_dist) { +void GeometryInstance::set_lod_max_distance(float p_dist) { - draw_end=p_dist; - VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),draw_begin,draw_end); + lod_max_distance=p_dist; + VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),lod_min_distance,lod_max_distance,lod_min_hysteresis,lod_max_hysteresis); } -float GeometryInstance::get_draw_range_end() const { +float GeometryInstance::get_lod_max_distance() const { - return draw_end; + return lod_max_distance; } -void GeometryInstance::_notification(int p_what) { +void GeometryInstance::set_lod_min_hysteresis(float p_dist){ - if (p_what==NOTIFICATION_ENTER_WORLD) { + lod_min_hysteresis=p_dist; + VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),lod_min_distance,lod_max_distance,lod_min_hysteresis,lod_max_hysteresis); +} - if (flags[FLAG_USE_BAKED_LIGHT]) { +float GeometryInstance::get_lod_min_hysteresis() const{ - _find_baked_light(); - } + return lod_min_hysteresis; +} - _update_visibility(); - } else if (p_what==NOTIFICATION_EXIT_WORLD) { +void GeometryInstance::set_lod_max_hysteresis(float p_dist) { - if (flags[FLAG_USE_BAKED_LIGHT]) { + lod_max_hysteresis=p_dist; + VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),lod_min_distance,lod_max_distance,lod_min_hysteresis,lod_max_hysteresis); - if (baked_light_instance) { - baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed); - baked_light_instance=NULL; - } - _baked_light_changed(); +} - } +float GeometryInstance::get_lod_max_hysteresis() const { - } if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { - - _update_visibility(); - } + return lod_max_hysteresis; +} -} +void GeometryInstance::_notification(int p_what) { -void GeometryInstance::_baked_light_changed() { + if (p_what==NOTIFICATION_ENTER_WORLD) { - if (!baked_light_instance) - VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),RID()); - else - VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),baked_light_instance->get_baked_light_instance()); + if (flags[FLAG_USE_BAKED_LIGHT]) { -} + } -void GeometryInstance::_find_baked_light() { + _update_visibility(); - Node *n=get_parent(); - while(n) { + } else if (p_what==NOTIFICATION_EXIT_WORLD) { - BakedLightInstance *bl=n->cast_to<BakedLightInstance>(); - if (bl) { + if (flags[FLAG_USE_BAKED_LIGHT]) { - baked_light_instance=bl; - baked_light_instance->connect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed); - _baked_light_changed(); - return; } - n=n->get_parent(); + } if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { + + _update_visibility(); } - _baked_light_changed(); + } void GeometryInstance::_update_visibility() { @@ -288,17 +276,6 @@ void GeometryInstance::set_flag(Flags p_flag,bool p_value) { } if (p_flag==FLAG_USE_BAKED_LIGHT) { - if (is_inside_world()) { - if (!p_value) { - if (baked_light_instance) { - baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed); - baked_light_instance=NULL; - } - _baked_light_changed(); - } else { - _find_baked_light(); - } - } } } @@ -331,17 +308,8 @@ GeometryInstance::ShadowCastingSetting GeometryInstance::get_cast_shadows_settin return shadow_casting_setting; } -void GeometryInstance::set_baked_light_texture_id(int p_id) { - - baked_light_texture_id=p_id; - VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),baked_light_texture_id); - -} -int GeometryInstance::get_baked_light_texture_id() const{ - return baked_light_texture_id; -} void GeometryInstance::set_extra_cull_margin(float p_margin) { @@ -366,41 +334,43 @@ void GeometryInstance::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_cast_shadows_setting", "shadow_casting_setting"), &GeometryInstance::set_cast_shadows_setting); ObjectTypeDB::bind_method(_MD("get_cast_shadows_setting"), &GeometryInstance::get_cast_shadows_setting); - ObjectTypeDB::bind_method(_MD("set_draw_range_begin","mode"), &GeometryInstance::set_draw_range_begin); - ObjectTypeDB::bind_method(_MD("get_draw_range_begin"), &GeometryInstance::get_draw_range_begin); + ObjectTypeDB::bind_method(_MD("set_lod_max_hysteresis","mode"), &GeometryInstance::set_lod_max_hysteresis); + ObjectTypeDB::bind_method(_MD("get_lod_max_hysteresis"), &GeometryInstance::get_lod_max_hysteresis); + + ObjectTypeDB::bind_method(_MD("set_lod_max_distance","mode"), &GeometryInstance::set_lod_max_distance); + ObjectTypeDB::bind_method(_MD("get_lod_max_distance"), &GeometryInstance::get_lod_max_distance); + + ObjectTypeDB::bind_method(_MD("set_lod_min_hysteresis","mode"), &GeometryInstance::set_lod_min_hysteresis); + ObjectTypeDB::bind_method(_MD("get_lod_min_hysteresis"), &GeometryInstance::get_lod_min_hysteresis); - ObjectTypeDB::bind_method(_MD("set_draw_range_end","mode"), &GeometryInstance::set_draw_range_end); - ObjectTypeDB::bind_method(_MD("get_draw_range_end"), &GeometryInstance::get_draw_range_end); + ObjectTypeDB::bind_method(_MD("set_lod_min_distance","mode"), &GeometryInstance::set_lod_min_distance); + ObjectTypeDB::bind_method(_MD("get_lod_min_distance"), &GeometryInstance::get_lod_min_distance); - ObjectTypeDB::bind_method(_MD("set_baked_light_texture_id","id"), &GeometryInstance::set_baked_light_texture_id); - ObjectTypeDB::bind_method(_MD("get_baked_light_texture_id"), &GeometryInstance::get_baked_light_texture_id); ObjectTypeDB::bind_method(_MD("set_extra_cull_margin","margin"), &GeometryInstance::set_extra_cull_margin); ObjectTypeDB::bind_method(_MD("get_extra_cull_margin"), &GeometryInstance::get_extra_cull_margin); ObjectTypeDB::bind_method(_MD("get_aabb"),&GeometryInstance::get_aabb); - ObjectTypeDB::bind_method(_MD("_baked_light_changed"), &GeometryInstance::_baked_light_changed); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE); ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "geometry/material_override",PROPERTY_HINT_RESOURCE_TYPE,"Material"), _SCS("set_material_override"), _SCS("get_material_override")); ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), _SCS("set_cast_shadows_setting"), _SCS("get_cast_shadows_setting")); - ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/receive_shadows"), _SCS("set_flag"), _SCS("get_flag"),FLAG_RECEIVE_SHADOWS); - ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_begin",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_begin"), _SCS("get_draw_range_begin")); - ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_end",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_end"), _SCS("get_draw_range_end")); ADD_PROPERTY( PropertyInfo( Variant::REAL, "geometry/extra_cull_margin",PROPERTY_HINT_RANGE,"0,16384,0"), _SCS("set_extra_cull_margin"), _SCS("get_extra_cull_margin")); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard_y"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD_FIX_Y); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/depth_scale"), _SCS("set_flag"), _SCS("get_flag"),FLAG_DEPH_SCALE); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible_in_all_rooms"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE_IN_ALL_ROOMS); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/use_baked_light"), _SCS("set_flag"), _SCS("get_flag"),FLAG_USE_BAKED_LIGHT); - ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/baked_light_tex_id"), _SCS("set_baked_light_texture_id"), _SCS("get_baked_light_texture_id")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/min_distance",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_min_distance"), _SCS("get_lod_min_distance")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/min_hysteresis",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_min_hysteresis"), _SCS("get_lod_min_hysteresis")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/max_distance",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_max_distance"), _SCS("get_lod_max_distance")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/max_hysteresis",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_max_hysteresis"), _SCS("get_lod_max_hysteresis")); // ADD_SIGNAL( MethodInfo("visibility_changed")); BIND_CONSTANT(FLAG_VISIBLE ); BIND_CONSTANT(FLAG_CAST_SHADOW ); - BIND_CONSTANT(FLAG_RECEIVE_SHADOWS ); BIND_CONSTANT(FLAG_BILLBOARD ); BIND_CONSTANT(FLAG_BILLBOARD_FIX_Y ); BIND_CONSTANT(FLAG_DEPH_SCALE ); @@ -415,20 +385,21 @@ void GeometryInstance::_bind_methods() { } GeometryInstance::GeometryInstance() { - draw_begin=0; - draw_end=0; + lod_min_distance=0; + lod_max_distance=0; + lod_min_hysteresis=0; + lod_max_hysteresis=0; + for(int i=0;i<FLAG_MAX;i++) { flags[i]=false; } flags[FLAG_VISIBLE]=true; flags[FLAG_CAST_SHADOW]=true; - flags[FLAG_RECEIVE_SHADOWS]=true; + shadow_casting_setting=SHADOW_CASTING_SETTING_ON; - baked_light_instance=NULL; - baked_light_texture_id=0; extra_cull_margin=0; - VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0); +// VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0); } diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index 1670c4679a..5fa2eeeeda 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -79,7 +79,7 @@ public: }; -class BakedLightInstance; +class BakedLight; class GeometryInstance : public VisualInstance { @@ -89,7 +89,6 @@ public: enum Flags { FLAG_VISIBLE=VS::INSTANCE_FLAG_VISIBLE, FLAG_CAST_SHADOW=VS::INSTANCE_FLAG_CAST_SHADOW, - FLAG_RECEIVE_SHADOWS=VS::INSTANCE_FLAG_RECEIVE_SHADOWS, FLAG_BILLBOARD=VS::INSTANCE_FLAG_BILLBOARD, FLAG_BILLBOARD_FIX_Y=VS::INSTANCE_FLAG_BILLBOARD_FIX_Y, FLAG_DEPH_SCALE=VS::INSTANCE_FLAG_DEPH_SCALE, @@ -98,6 +97,7 @@ public: FLAG_MAX=VS::INSTANCE_FLAG_MAX, }; + enum ShadowCastingSetting { SHADOW_CASTING_SETTING_OFF=VS::SHADOW_CASTING_SETTING_OFF, SHADOW_CASTING_SETTING_ON = VS::SHADOW_CASTING_SETTING_ON, @@ -110,14 +110,13 @@ private: bool flags[FLAG_MAX]; ShadowCastingSetting shadow_casting_setting; Ref<Material> material_override; - float draw_begin; - float draw_end; - void _find_baked_light(); - BakedLightInstance *baked_light_instance; - int baked_light_texture_id; + float lod_min_distance; + float lod_max_distance; + float lod_min_hysteresis; + float lod_max_hysteresis; + float extra_cull_margin; - void _baked_light_changed(); void _update_visibility(); protected: @@ -131,18 +130,21 @@ public: void set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting); ShadowCastingSetting get_cast_shadows_setting() const; - void set_draw_range_begin(float p_dist); - float get_draw_range_begin() const; + void set_lod_min_distance(float p_dist); + float get_lod_min_distance() const; + + void set_lod_max_distance(float p_dist); + float get_lod_max_distance() const; - void set_draw_range_end(float p_dist); - float get_draw_range_end() const; + void set_lod_min_hysteresis(float p_dist); + float get_lod_min_hysteresis() const; + + void set_lod_max_hysteresis(float p_dist); + float get_lod_max_hysteresis() const; void set_material_override(const Ref<Material>& p_material); Ref<Material> get_material_override() const; - void set_baked_light_texture_id(int p_id); - int get_baked_light_texture_id() const; - void set_extra_cull_margin(float p_margin); float get_extra_cull_margin() const; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index a65c85d24c..6c212f60f0 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -34,38 +34,21 @@ #include "os/input.h" #include "os/keyboard.h" -void update_material(Ref<CanvasItemMaterial>mat,const Color& p_color,float h,float s,float v) { - if (!mat.is_valid()) - return; - Ref<Shader> sdr = mat->get_shader(); - if (!sdr.is_valid()) - return; - - mat->set_shader_param("R",p_color.r); - mat->set_shader_param("G",p_color.g); - mat->set_shader_param("B",p_color.b); - mat->set_shader_param("H",h); - mat->set_shader_param("S",s); - mat->set_shader_param("V",v); - mat->set_shader_param("A",p_color.a); -} void ColorPicker::_notification(int p_what) { switch(p_what) { case NOTIFICATION_THEME_CHANGED: { - uv_material->set_shader(get_shader("uv_editor")); - w_material->set_shader(get_shader("w_editor")); - update_material(uv_material,color,h,s,v); - update_material(w_material,color,h,s,v); + uv_edit->set_texture(get_icon("color_main")); + w_edit->set_texture(get_icon("color_hue")); + sample->set_texture(get_icon("color_sample")); + _update_controls(); } break; case NOTIFICATION_ENTER_TREE: { btn_pick->set_icon(get_icon("screen_picker", "ColorPicker")); - update_material(uv_material, color,h,s,v); - update_material(w_material, color,h,s,v); uv_edit->get_child(0)->cast_to<Control>()->update(); w_edit->get_child(0)->cast_to<Control>()->update(); @@ -109,8 +92,6 @@ void ColorPicker::set_color(const Color& p_color) { if (!is_inside_tree()) return; - update_material(uv_material, color,h,s,v); - update_material(w_material, color,h,s,v); uv_edit->get_child(0)->cast_to<Control>()->update(); w_edit->get_child(0)->cast_to<Control>()->update(); @@ -192,10 +173,24 @@ void ColorPicker::_update_presets() { Size2 size=bt_add_preset->get_size(); preset->set_custom_minimum_size(Size2(size.width*presets.size(),size.height)); - Image i(size.x*presets.size(),size.y, false, Image::FORMAT_RGB); - for (int y=0;y<size.y;y++) - for (int x=0;x<size.x*presets.size();x++) - i.put_pixel(x,y,presets[(int)x/size.x]); + + DVector<uint8_t> img; + img.resize(size.x*presets.size()*size.y*3); + + { + DVector<uint8_t>::Write w=img.write(); + for (int y=0;y<size.y;y++) { + for (int x=0;x<size.x*presets.size();x++) { + int ofs = (y*(size.x*presets.size())+x)*3; + w[ofs+0]=uint8_t(CLAMP(presets[(int)x/size.x].r*255.0,0,255)); + w[ofs+1]=uint8_t(CLAMP(presets[(int)x/size.x].g*255.0,0,255)); + w[ofs+2]=uint8_t(CLAMP(presets[(int)x/size.x].b*255.0,0,255)); + } + } + } + + Image i(size.x*presets.size(),size.y, false, Image::FORMAT_RGB8,img); + Ref<ImageTexture> t; t.instance(); t->create_from_image(i); @@ -394,15 +389,23 @@ void ColorPicker::_screen_input(const InputEvent &ev) } else if (ev.type==InputEvent::MOUSE_MOTION) { const InputEventMouse &mev = ev.mouse_motion; Viewport *r=get_tree()->get_root(); - if (!r->get_rect().has_point(Point2(mev.global_x,mev.global_y))) + if (!r->get_visible_rect().has_point(Point2(mev.global_x,mev.global_y))) return; Image img =r->get_screen_capture(); if (!img.empty()) { last_capture=img; r->queue_screen_capture(); } - if (!last_capture.empty()) - set_color(last_capture.get_pixel(mev.global_x,mev.global_y)); + if (!last_capture.empty()) { + int pw = last_capture.get_format()==Image::FORMAT_RGBA8?4:3; + int ofs = (mev.global_y*last_capture.get_width()+mev.global_x)*pw; + + DVector<uint8_t>::Read r = last_capture.get_data().read(); + + Color c( r[ofs+0]/255.0, r[ofs+1]/255.0, r[ofs+2]/255.0 ); + + set_color(c); + } } } @@ -474,22 +477,15 @@ ColorPicker::ColorPicker() : HBoxContainer *hb_edit = memnew( HBoxContainer ); uv_edit= memnew ( TextureFrame ); - Image i(256, 256, false, Image::FORMAT_RGB); - for (int y=0;y<256;y++) - for (int x=0;x<256;x++) - i.put_pixel(x,y,Color()); - Ref<ImageTexture> t; - t.instance(); - t->create_from_image(i); - uv_edit->set_texture(t); + + + uv_edit->set_ignore_mouse(false); - uv_edit->set_custom_minimum_size(Size2(256,256)); uv_edit->connect("input_event", this, "_uv_input"); Control *c= memnew( Control ); uv_edit->add_child(c); c->set_area_as_parent_rect(); c->set_stop_mouse(false); - c->set_material(memnew ( CanvasItemMaterial )); Vector<Variant> args=Vector<Variant>(); args.push_back(0); args.push_back(c); @@ -497,22 +493,14 @@ ColorPicker::ColorPicker() : add_child(hb_edit); w_edit= memnew( TextureFrame ); - i = Image(15, 256, false, Image::FORMAT_RGB); - for (int y=0;y<256;y++) - for (int x=0;x<15;x++) - i.put_pixel(x,y,Color()); - Ref<ImageTexture> tw; - tw.instance(); - tw->create_from_image(i); - w_edit->set_texture(tw); - w_edit->set_ignore_mouse(false); - w_edit->set_custom_minimum_size(Size2(15,256)); + + + w_edit->set_ignore_mouse(false); w_edit->connect("input_event", this, "_w_input"); c= memnew( Control ); w_edit->add_child(c); c->set_area_as_parent_rect(); c->set_stop_mouse(false); - c->set_material(memnew ( CanvasItemMaterial )); args.clear(); args.push_back(1); args.push_back(c); @@ -580,31 +568,8 @@ ColorPicker::ColorPicker() : //_update_color(); updating=false; - uv_material.instance(); - Ref<Shader> s_uv = get_shader("uv_editor"); - uv_material->set_shader(s_uv); - - w_material.instance(); - - Ref<Shader> s_w = get_shader("w_editor"); - w_material->set_shader(s_w); - - uv_edit->set_material(uv_material); - w_edit->set_material(w_material); - set_color(Color(1,1,1)); - i.create(256,20,false,Image::FORMAT_RGB); - for (int y=0;y<20;y++) - for(int x=0;x<256;x++) - if ((x/4+y/4)%2) - i.put_pixel(x,y,Color(1,1,1)); - else - i.put_pixel(x,y,Color(0.6,0.6,0.6)); - Ref<ImageTexture> t_smpl; - t_smpl.instance(); - t_smpl->create_from_image(i); - sample->set_texture(t_smpl); HBoxContainer *bbc = memnew( HBoxContainer ); add_child(bbc); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 5832f7db72..1b7f96acf5 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -57,8 +57,6 @@ private: List<Color> presets; ToolButton *btn_pick; CheckButton *btn_mode; - Ref<CanvasItemMaterial> uv_material; - Ref<CanvasItemMaterial> w_material; HSlider *scroll[4]; SpinBox *values[4]; Label *labels[4]; diff --git a/scene/gui/patch_9_frame.cpp b/scene/gui/patch_9_frame.cpp index 40d3cb0e0f..2553bb952b 100644 --- a/scene/gui/patch_9_frame.cpp +++ b/scene/gui/patch_9_frame.cpp @@ -39,7 +39,7 @@ void Patch9Frame::_notification(int p_what) { Size2 s=get_size(); RID ci = get_canvas_item(); - VS::get_singleton()->canvas_item_add_style_box(ci,Rect2(Point2(),s),region_rect,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center,modulate); + VS::get_singleton()->canvas_item_add_nine_patch(ci,Rect2(Point2(),s),region_rect,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),VS::NINE_PATCH_STRETCH,VS::NINE_PATCH_STRETCH,draw_center,modulate); // draw_texture_rect(texture,Rect2(Point2(),s),false,modulate); /* diff --git a/scene/gui/viewport_container.cpp b/scene/gui/viewport_container.cpp new file mode 100644 index 0000000000..3418a495e9 --- /dev/null +++ b/scene/gui/viewport_container.cpp @@ -0,0 +1,103 @@ +#include "viewport_container.h" +#include "scene/main/viewport.h" +Size2 ViewportContainer::get_minimum_size() const { + + + if (stretch) + return Size2(); + Size2 ms; + for(int i=0;i<get_child_count();i++) { + + Viewport *c = get_child(i)->cast_to<Viewport>(); + if (!c) + continue; + + Size2 minsize = c->get_size(); + ms.width = MAX(ms.width , minsize.width); + ms.height = MAX(ms.height , minsize.height); + } + + return ms; + +} + + +void ViewportContainer::set_stretch(bool p_enable) { + + stretch=p_enable; + queue_sort(); + update(); + +} + +bool ViewportContainer::is_stretch_enabled() const { + + return stretch; +} + + +void ViewportContainer::_notification(int p_what) { + + + if (p_what==NOTIFICATION_RESIZED) { + + if (!stretch) + return; + + for(int i=0;i<get_child_count();i++) { + + Viewport *c = get_child(i)->cast_to<Viewport>(); + if (!c) + continue; + + c->set_size(get_size()); + } + } + + if (p_what==NOTIFICATION_ENTER_TREE || p_what==NOTIFICATION_VISIBILITY_CHANGED) { + + for(int i=0;i<get_child_count();i++) { + + Viewport *c = get_child(i)->cast_to<Viewport>(); + if (!c) + continue; + + + if (is_visible()) + c->set_update_mode(Viewport::UPDATE_ALWAYS); + else + c->set_update_mode(Viewport::UPDATE_DISABLED); + } + + } + + if (p_what==NOTIFICATION_DRAW) { + + for(int i=0;i<get_child_count();i++) { + + + Viewport *c = get_child(i)->cast_to<Viewport>(); + if (!c) + continue; + + if (stretch) + draw_texture_rect(c->get_texture(),Rect2(Vector2(),get_size()*Size2(1,-1))); + else + draw_texture_rect(c->get_texture(),Rect2(Vector2(),c->get_size()*Size2(1,-1))); + } + } + +} + +void ViewportContainer::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_stretch","enable"),&ViewportContainer::set_stretch); + ObjectTypeDB::bind_method(_MD("is_stretch_enabled"),&ViewportContainer::is_stretch_enabled); + + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"stretch"),_SCS("set_stretch"),_SCS("is_stretch_enabled")); +} + +ViewportContainer::ViewportContainer() { + + stretch=false; +} diff --git a/scene/gui/viewport_container.h b/scene/gui/viewport_container.h new file mode 100644 index 0000000000..cfc58f7d6e --- /dev/null +++ b/scene/gui/viewport_container.h @@ -0,0 +1,25 @@ +#ifndef VIEWPORTCONTAINER_H +#define VIEWPORTCONTAINER_H + +#include "scene/gui/container.h" + +class ViewportContainer : public Container { + + OBJ_TYPE( ViewportContainer, Container ); + + bool stretch; +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_stretch(bool p_enable); + bool is_stretch_enabled() const; + + virtual Size2 get_minimum_size() const; + + ViewportContainer(); +}; + +#endif // VIEWPORTCONTAINER_H diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 1de19959db..9f20e0f845 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -246,6 +246,15 @@ Node* CanvasLayer::get_custom_viewport() const { return custom_viewport; } +void CanvasLayer::reset_sort_index() { + sort_index=0; +} + +int CanvasLayer::get_sort_index() { + + return sort_index++; +} + void CanvasLayer::_bind_methods() { @@ -296,4 +305,5 @@ CanvasLayer::CanvasLayer() { canvas = Ref<World2D>( memnew(World2D) ); custom_viewport=NULL; custom_viewport_id=0; + sort_index=0; } diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index 039db8823e..2e3c917205 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -52,6 +52,8 @@ class CanvasLayer : public Node { RID viewport; Viewport *vp; + int sort_index; + // Deprecated, should be removed in a future version. void _set_rotationd(real_t p_rotation); real_t _get_rotationd() const; @@ -93,6 +95,9 @@ public: void set_custom_viewport(Node *p_viewport); Node* get_custom_viewport() const; + void reset_sort_index(); + int get_sort_index(); + CanvasLayer(); }; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 9c97ca4424..23230a8b40 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -316,6 +316,12 @@ void Node::move_child(Node *p_child,int p_pos) { } + if (p_child->data.pos==p_pos) + return; //do nothing + + int motion_from = MIN(p_pos,p_child->data.pos); + int motion_to = MAX(p_pos,p_child->data.pos); + data.children.remove( p_child->data.pos ); data.children.insert( p_pos, p_child ); @@ -325,13 +331,13 @@ void Node::move_child(Node *p_child,int p_pos) { data.blocked++; //new pos first - for (int i=0;i<data.children.size();i++) { + for (int i=motion_from;i<=motion_to;i++) { data.children[i]->data.pos=i; } // notification second move_child_notify(p_child); - for (int i=0;i<data.children.size();i++) { + for (int i=motion_from;i<=motion_to;i++) { data.children[i]->notification( NOTIFICATION_MOVED_IN_PARENT ); } diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index f0c1251e43..874562ad3b 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -490,6 +490,8 @@ void SceneTree::input_event( const InputEvent& p_event ) { } + _call_idle_callbacks(); + } void SceneTree::init() { @@ -528,6 +530,7 @@ bool SceneTree::iteration(float p_time) { root_lock--; _flush_delete_queue(); + _call_idle_callbacks(); return _quit; } @@ -590,6 +593,8 @@ bool SceneTree::idle(float p_time){ E=N; } + _call_idle_callbacks(); + return _quit; } @@ -745,12 +750,12 @@ Ref<Material> SceneTree::get_debug_navigation_material() { if (navigation_material.is_valid()) return navigation_material; - Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial )); - line_material->set_flag(Material::FLAG_UNSHADED, true); + Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); +/* line_material->set_flag(Material::FLAG_UNSHADED, true); line_material->set_line_width(3.0); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); - line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_navigation_color()); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true); + line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_color());*/ navigation_material=line_material; @@ -763,12 +768,12 @@ Ref<Material> SceneTree::get_debug_navigation_disabled_material(){ if (navigation_disabled_material.is_valid()) return navigation_disabled_material; - Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial )); - line_material->set_flag(Material::FLAG_UNSHADED, true); + Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); +/* line_material->set_flag(Material::FLAG_UNSHADED, true); line_material->set_line_width(3.0); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); - line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_navigation_disabled_color()); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true); + line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_navigation_disabled_color());*/ navigation_disabled_material=line_material; @@ -781,12 +786,12 @@ Ref<Material> SceneTree::get_debug_collision_material() { return collision_material; - Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial )); - line_material->set_flag(Material::FLAG_UNSHADED, true); + Ref<FixedSpatialMaterial> line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); + /*line_material->set_flag(Material::FLAG_UNSHADED, true); line_material->set_line_width(3.0); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); - line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_collisions_color()); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true); + line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_collisions_color());*/ collision_material=line_material; @@ -800,11 +805,11 @@ Ref<Mesh> SceneTree::get_debug_contact_mesh() { debug_contact_mesh = Ref<Mesh>( memnew( Mesh ) ); - Ref<FixedMaterial> mat = memnew( FixedMaterial ); - mat->set_flag(Material::FLAG_UNSHADED,true); + Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial ); + /*mat->set_flag(Material::FLAG_UNSHADED,true); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); - mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true); - mat->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_collision_contact_color()); + mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,get_debug_collision_contact_color());*/ Vector3 diamond[6]={ Vector3(-1, 0, 0), @@ -840,7 +845,7 @@ Ref<Mesh> SceneTree::get_debug_contact_mesh() { arr[Mesh::ARRAY_INDEX]=indices; - debug_contact_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,arr); + debug_contact_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES,arr); debug_contact_mesh->surface_set_material(0,mat); return debug_contact_mesh; @@ -1098,7 +1103,11 @@ void SceneTree::_update_root_rect() { if (stretch_mode==STRETCH_MODE_DISABLED) { - root->set_rect(Rect2(Point2(),last_screen_size)); + + root->set_size(last_screen_size); + root->set_attach_to_screen_rect(Rect2(Point2(),last_screen_size)); + root->set_size_override_stretch(false); + root->set_size_override(false,Size2()); return; //user will take care } @@ -1174,21 +1183,18 @@ void SceneTree::_update_root_rect() { switch (stretch_mode) { case STRETCH_MODE_2D: { -// root->set_rect(Rect2(Point2(),video_mode)); - root->set_as_render_target(false); - root->set_rect(Rect2(margin,screen_size)); + root->set_size(screen_size); + root->set_attach_to_screen_rect(Rect2(margin,screen_size)); root->set_size_override_stretch(true); root->set_size_override(true,viewport_size); } break; case STRETCH_MODE_VIEWPORT: { - root->set_rect(Rect2(Point2(),viewport_size)); + root->set_size(viewport_size); + root->set_attach_to_screen_rect(Rect2(margin,screen_size)); root->set_size_override_stretch(false); root->set_size_override(false,Size2()); - root->set_as_render_target(true); - root->set_render_target_update_mode(Viewport::RENDER_TARGET_UPDATE_ALWAYS); - root->set_render_target_to_screen_rect(Rect2(margin,screen_size)); } break; @@ -2258,6 +2264,23 @@ void SceneTree::_bind_methods() { SceneTree *SceneTree::singleton=NULL; + +SceneTree::IdleCallback SceneTree::idle_callbacks[SceneTree::MAX_IDLE_CALLBACKS]; +int SceneTree::idle_callback_count=0; + +void SceneTree::_call_idle_callbacks() { + + for(int i=0;i<idle_callback_count;i++) { + idle_callbacks[i](); + } +} + +void SceneTree::add_idle_callback(IdleCallback p_callback) { + ERR_FAIL_COND(idle_callback_count>=MAX_IDLE_CALLBACKS); + idle_callbacks[idle_callback_count++]=p_callback; +} + + SceneTree::SceneTree() { singleton=this; @@ -2273,6 +2296,7 @@ SceneTree::SceneTree() { collision_debug_contacts=GLOBAL_DEF("debug/collision_max_contacts_displayed",10000); + tree_version=1; fixed_process_time=1; idle_process_time=1; @@ -2296,11 +2320,22 @@ SceneTree::SceneTree() { root->set_as_audio_listener_2d(true); current_scene=NULL; + int ref_atlas_size = GLOBAL_DEF("rendering/reflections/atlas_size",2048); + int ref_atlas_subdiv = GLOBAL_DEF("rendering/reflections/atlas_subdiv",8); + int msaa_mode = GLOBAL_DEF("rendering/antialias/msaa",0); + Globals::get_singleton()->set_custom_property_info("rendering/antialias/msaa",PropertyInfo(Variant::INT,"rendering/antialias/msaa",PROPERTY_HINT_ENUM,"Disabled,2x,4x,8x,16x")); + root->set_msaa(Viewport::MSAA(msaa_mode)); + bool hdr = GLOBAL_DEF("rendering/dynamic_range/hdr",true); + root->set_hdr(hdr); + + VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(),ref_atlas_size,ref_atlas_subdiv); + + stretch_mode=STRETCH_MODE_DISABLED; stretch_aspect=STRETCH_ASPECT_IGNORE; last_screen_size=Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height ); - root->set_rect(Rect2(Point2(),last_screen_size)); + root->set_size(last_screen_size); if (ScriptDebugger::get_singleton()) { ScriptDebugger::get_singleton()->set_request_scene_tree_message_func(_debugger_request_tree,this); diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index 9380011078..915a78918a 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -74,6 +74,8 @@ class SceneTree : public MainLoop { public: + typedef void (*IdleCallback)(); + enum StretchMode { STRETCH_MODE_DISABLED, @@ -303,6 +305,15 @@ friend class Viewport; static void _live_edit_reparent_node_funcs(void* self,const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos) { reinterpret_cast<SceneTree*>(self)->_live_edit_reparent_node_func(p_at,p_new_place,p_new_name,p_at_pos); } #endif + + enum { + MAX_IDLE_CALLBACKS=256 + }; + + static IdleCallback idle_callbacks[MAX_IDLE_CALLBACKS]; + static int idle_callback_count; + void _call_idle_callbacks(); + protected: @@ -430,6 +441,7 @@ public: void set_refuse_new_network_connections(bool p_refuse); bool is_refusing_new_network_connections() const; + static void add_idle_callback(IdleCallback p_callback); SceneTree(); ~SceneTree(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 5bb5e918b1..ff148cc413 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -51,50 +51,52 @@ #include "globals.h" -int RenderTargetTexture::get_width() const { +int ViewportTexture::get_width() const { ERR_FAIL_COND_V(!vp,0); - return vp->rect.size.width; + return vp->size.width; } -int RenderTargetTexture::get_height() const{ +int ViewportTexture::get_height() const{ ERR_FAIL_COND_V(!vp,0); - return vp->rect.size.height; + return vp->size.height; } -Size2 RenderTargetTexture::get_size() const{ +Size2 ViewportTexture::get_size() const{ ERR_FAIL_COND_V(!vp,Size2()); - return vp->rect.size; + return vp->size; } -RID RenderTargetTexture::get_rid() const{ +RID ViewportTexture::get_rid() const{ ERR_FAIL_COND_V(!vp,RID()); - return vp->render_target_texture_rid; + return vp->texture_rid; } -bool RenderTargetTexture::has_alpha() const{ +bool ViewportTexture::has_alpha() const{ return false; } -void RenderTargetTexture::set_flags(uint32_t p_flags){ +void ViewportTexture::set_flags(uint32_t p_flags){ + + if (!vp) + return; - ERR_FAIL_COND(!vp); if (p_flags&FLAG_FILTER) flags=FLAG_FILTER; else flags=0; - VS::get_singleton()->texture_set_flags(vp->render_target_texture_rid,flags); + VS::get_singleton()->texture_set_flags(vp->texture_rid,flags); } -uint32_t RenderTargetTexture::get_flags() const{ +uint32_t ViewportTexture::get_flags() const{ return flags; } -RenderTargetTexture::RenderTargetTexture(Viewport *p_vp){ +ViewportTexture::ViewportTexture(Viewport *p_vp){ vp=p_vp; flags=0; @@ -141,9 +143,9 @@ 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("rect size "+size); stretch_transform=Matrix32(); - Size2 scale = rect.size/(size_override_size+size_override_margin*2); + Size2 scale = size/(size_override_size+size_override_margin*2); stretch_transform.scale(scale); stretch_transform.elements[2]=size_override_margin*scale; @@ -164,14 +166,14 @@ void Viewport::_update_rect() { return; - if (!render_target && parent_control) { + /*if (!render_target && parent_control) { Control *c = parent_control; rect.pos=Point2(); rect.size=c->get_size(); - } - + }*/ +/* VisualServer::ViewportRect vr; vr.x=rect.pos.x; vr.y=rect.pos.y; @@ -191,8 +193,8 @@ void Viewport::_update_rect() { } emit_signal("size_changed"); - render_target_texture->emit_changed(); - + texture->emit_changed(); +*/ } @@ -207,7 +209,7 @@ void Viewport::_parent_draw() { void Viewport::_parent_visibility_changed() { - +/* if (parent_control) { Control *c = parent_control; @@ -216,14 +218,14 @@ void Viewport::_parent_visibility_changed() { _update_listener(); _update_listener_2d(); } - +*/ } void Viewport::_vp_enter_tree() { - if (parent_control) { +/* if (parent_control) { Control *cparent=parent_control; RID parent_ci = cparent->get_canvas_item(); @@ -232,20 +234,21 @@ void Viewport::_vp_enter_tree() { VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,parent_ci); VisualServer::get_singleton()->canvas_item_set_visible(canvas_item,false); - VisualServer::get_singleton()->canvas_item_attach_viewport(canvas_item,viewport); +// VisualServer::get_singleton()->canvas_item_attach_viewport(canvas_item,viewport); parent_control->connect("resized",this,"_parent_resized"); parent_control->connect("visibility_changed",this,"_parent_visibility_changed"); } else if (!parent){ - VisualServer::get_singleton()->viewport_attach_to_screen(viewport,0); +// VisualServer::get_singleton()->viewport_attach_to_screen(viewport,0); } - +*/ } void Viewport::_vp_exit_tree() { + /* if (parent_control) { parent_control->disconnect("resized",this,"_parent_resized"); @@ -268,7 +271,7 @@ void Viewport::_vp_exit_tree() { VisualServer::get_singleton()->viewport_detach(viewport); } - +*/ } @@ -326,31 +329,12 @@ void Viewport::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { if (get_parent()) { - Node *parent=get_parent(); - if (parent) { - parent_control=parent->cast_to<Control>(); - } - } - - - parent=NULL; - Node *parent_node=get_parent(); - - - while(parent_node) { - - parent = parent_node->cast_to<Viewport>(); - if (parent) - break; - - parent_node=parent_node->get_parent(); + parent = get_parent()->get_viewport(); + VisualServer::get_singleton()->viewport_set_parent_viewport(viewport,parent->get_viewport()); + } else { + parent=NULL; } - - if (!render_target) - _vp_enter_tree(); - - current_canvas=find_world_2d()->get_canvas(); VisualServer::get_singleton()->viewport_set_scenario(viewport,find_world()->get_scenario()); VisualServer::get_singleton()->viewport_attach_canvas(viewport,current_canvas); @@ -370,7 +354,7 @@ void Viewport::_notification(int p_what) { //3D PhysicsServer::get_singleton()->space_set_debug_contacts(find_world()->get_space(),get_tree()->get_collision_debug_contact_count()); contact_3d_debug_multimesh=VisualServer::get_singleton()->multimesh_create(); - VisualServer::get_singleton()->multimesh_set_instance_count(contact_3d_debug_multimesh,get_tree()->get_collision_debug_contact_count()); + VisualServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh,get_tree()->get_collision_debug_contact_count(),VS::MULTIMESH_TRANSFORM_3D,VS::MULTIMESH_COLOR_8BIT); VisualServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh,0); VisualServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh,get_tree()->get_debug_contact_mesh()->get_rid()); contact_3d_debug_instance=VisualServer::get_singleton()->instance_create(); @@ -380,6 +364,7 @@ void Viewport::_notification(int p_what) { } + VS::get_singleton()->viewport_set_active(viewport,true); } break; case NOTIFICATION_READY: { #ifndef _3D_DISABLED @@ -418,8 +403,8 @@ void Viewport::_notification(int p_what) { if (world_2d.is_valid()) world_2d->_remove_viewport(this); - if (!render_target) - _vp_exit_tree(); + //if (!render_target) + // _vp_exit_tree(); VisualServer::get_singleton()->viewport_set_scenario(viewport,RID()); SpatialSoundServer::get_singleton()->listener_set_space(internal_listener, RID()); @@ -437,7 +422,10 @@ void Viewport::_notification(int p_what) { } remove_from_group("_viewports"); - parent_control=NULL; + + + VS::get_singleton()->viewport_set_active(viewport,false); + } break; case NOTIFICATION_FIXED_PROCESS: { @@ -452,7 +440,7 @@ void Viewport::_notification(int p_what) { if (get_tree()->is_debugging_collisions_hint() && contact_2d_debug.is_valid()) { VisualServer::get_singleton()->canvas_item_clear(contact_2d_debug); - VisualServer::get_singleton()->canvas_item_raise(contact_2d_debug); + VisualServer::get_singleton()->canvas_item_set_draw_index(contact_2d_debug,0xFFFFF); //very high index Vector<Vector2> points = Physics2DServer::get_singleton()->space_get_contacts(find_world_2d()->get_space()); int point_count = Physics2DServer::get_singleton()->space_get_contact_count(find_world_2d()->get_space()); @@ -474,27 +462,11 @@ void Viewport::_notification(int p_what) { VS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh,point_count); - if (point_count>0) { - AABB aabb; - - Transform t; - for(int i=0;i<point_count;i++) { - - if (i==0) - aabb.pos=points[i]; - else - aabb.expand_to(points[i]); - t.origin=points[i]; - VisualServer::get_singleton()->multimesh_instance_set_transform(contact_3d_debug_multimesh,i,t); - } - aabb.grow(aabb.get_longest_axis_size()*0.01); - VisualServer::get_singleton()->multimesh_set_aabb(contact_3d_debug_multimesh,aabb); - } } - if (physics_object_picking && (render_target || Input::get_singleton()->get_mouse_mode()!=Input::MOUSE_MODE_CAPTURED)) { + if (physics_object_picking && (to_screen_rect==Rect2() || Input::get_singleton()->get_mouse_mode()!=Input::MOUSE_MODE_CAPTURED)) { Vector2 last_pos(1e20,1e20); CollisionObject *last_object; @@ -708,15 +680,18 @@ RID Viewport::get_viewport() const { return viewport; } -void Viewport::set_rect(const Rect2& p_rect) { +void Viewport::set_size(const Size2 &p_size) { - if (rect==p_rect) + if (size==p_size.floor()) return; - rect=p_rect; + size=p_size.floor(); + VS::get_singleton()->viewport_set_size(viewport,size.width,size.height); _update_rect(); _update_stretch_transform(); + emit_signal("size_changed"); + } Rect2 Viewport::get_visible_rect() const { @@ -724,12 +699,12 @@ Rect2 Viewport::get_visible_rect() const { Rect2 r; - if (rect.pos==Vector2() && rect.size==Size2()) { + if (size==Size2()) { r=Rect2( Point2(), Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height ) ); } else { - r=Rect2( rect.pos , rect.size ); + r=Rect2( Point2() , size ); } if (size_override) { @@ -740,9 +715,9 @@ Rect2 Viewport::get_visible_rect() const { return r; } -Rect2 Viewport::get_rect() const { +Size2 Viewport::get_size() const { - return rect; + return size; } @@ -1219,10 +1194,10 @@ bool Viewport::is_size_override_stretch_enabled() const { return size_override_stretch; } - +#if 0 void Viewport::set_as_render_target(bool p_enable){ - if (render_target==p_enable) +/* if (render_target==p_enable) return; render_target=p_enable; @@ -1238,117 +1213,126 @@ void Viewport::set_as_render_target(bool p_enable){ if (p_enable) { - render_target_texture_rid = VS::get_singleton()->viewport_get_render_target_texture(viewport); + texture_rid = VS::get_singleton()->viewport_get_texture(viewport); } else { - render_target_texture_rid=RID(); + texture_rid=RID(); } - render_target_texture->set_flags(render_target_texture->flags); - render_target_texture->emit_changed(); + texture->set_flags(texture->flags); + texture->emit_changed(); update_configuration_warning(); + */ } bool Viewport::is_set_as_render_target() const{ return render_target; + } -void Viewport::set_render_target_update_mode(RenderTargetUpdateMode p_mode){ +#endif +void Viewport::set_update_mode(UpdateMode p_mode){ - render_target_update_mode=p_mode; - VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RenderTargetUpdateMode(p_mode)); + update_mode=p_mode; + VS::get_singleton()->viewport_set_update_mode(viewport,VS::ViewportUpdateMode(p_mode)); } -Viewport::RenderTargetUpdateMode Viewport::get_render_target_update_mode() const{ +Viewport::UpdateMode Viewport::get_update_mode() const{ - return render_target_update_mode; + return update_mode; } -//RID get_render_target_texture() const; +//RID get_texture() const; void Viewport::queue_screen_capture(){ - VS::get_singleton()->viewport_queue_screen_capture(viewport); + //VS::get_singleton()->viewport_queue_screen_capture(viewport); } Image Viewport::get_screen_capture() const { - return VS::get_singleton()->viewport_get_screen_capture(viewport); +// return VS::get_singleton()->viewport_get_screen_capture(viewport); + return Image(); } -Ref<RenderTargetTexture> Viewport::get_render_target_texture() const { +Ref<ViewportTexture> Viewport::get_texture() const { - return render_target_texture; + return texture; } -void Viewport::set_render_target_vflip(bool p_enable) { +void Viewport::set_vflip(bool p_enable) { - render_target_vflip=p_enable; - VisualServer::get_singleton()->viewport_set_render_target_vflip(viewport,p_enable); + vflip=p_enable; + VisualServer::get_singleton()->viewport_set_vflip(viewport,p_enable); } -bool Viewport::get_render_target_vflip() const{ +bool Viewport::get_vflip() const{ - return render_target_vflip; + return vflip; } -void Viewport::set_render_target_clear_on_new_frame(bool p_enable) { +void Viewport::set_clear_on_new_frame(bool p_enable) { - render_target_clear_on_new_frame=p_enable; - VisualServer::get_singleton()->viewport_set_render_target_clear_on_new_frame(viewport,p_enable); + clear_on_new_frame=p_enable; + //VisualServer::get_singleton()->viewport_set_clear_on_new_frame(viewport,p_enable); } -bool Viewport::get_render_target_clear_on_new_frame() const{ +bool Viewport::get_clear_on_new_frame() const{ - return render_target_clear_on_new_frame; + return clear_on_new_frame; } -void Viewport::render_target_clear() { +void Viewport::set_shadow_atlas_size(int p_size) { + + if (shadow_atlas_size==p_size) + return; - //render_target_clear=true; - VisualServer::get_singleton()->viewport_render_target_clear(viewport); + shadow_atlas_size=p_size; + VS::get_singleton()->viewport_set_shadow_atlas_size(viewport,p_size); } -void Viewport::set_render_target_filter(bool p_enable) { +int Viewport::get_shadow_atlas_size() const{ - if(!render_target) - return; + return shadow_atlas_size; +} - render_target_texture->set_flags(p_enable?int(Texture::FLAG_FILTER):int(0)); +void Viewport::set_shadow_atlas_quadrant_subdiv(int p_quadrant,ShadowAtlasQuadrantSubdiv p_subdiv){ -} -bool Viewport::get_render_target_filter() const{ + ERR_FAIL_INDEX(p_quadrant,4); + ERR_FAIL_INDEX(p_subdiv,SHADOW_ATLAS_QUADRANT_SUBDIV_MAX); - return (render_target_texture->get_flags()&Texture::FLAG_FILTER)!=0; -} + if (shadow_atlas_quadrant_subdiv[p_quadrant]==p_subdiv) + return; -void Viewport::set_render_target_gen_mipmaps(bool p_enable) { + shadow_atlas_quadrant_subdiv[p_quadrant]=p_subdiv; + static const int subdiv[SHADOW_ATLAS_QUADRANT_SUBDIV_MAX]={0,1,4,16,64,256,1024}; - //render_target_texture->set_flags(p_enable?int(Texture::FLAG_FILTER):int(0)); - render_target_gen_mipmaps=p_enable; + VS::get_singleton()->viewport_set_shadow_atlas_quadrant_subdivision(viewport,p_quadrant,subdiv[p_subdiv]); } +Viewport::ShadowAtlasQuadrantSubdiv Viewport::get_shadow_atlas_quadrant_subdiv(int p_quadrant) const{ + + ERR_FAIL_INDEX_V(p_quadrant,4,SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED); + return shadow_atlas_quadrant_subdiv[p_quadrant]; +} + -bool Viewport::get_render_target_gen_mipmaps() const{ +void Viewport::clear() { - //return (render_target_texture->get_flags()&Texture::FLAG_FILTER)!=0; - return render_target_gen_mipmaps; + //clear=true; +// VisualServer::get_singleton()->viewport_clear(viewport); } Matrix32 Viewport::_get_input_pre_xform() const { Matrix32 pre_xf; - if (render_target) { - if (to_screen_rect!=Rect2()) { - pre_xf.elements[2]=-to_screen_rect.pos; - pre_xf.scale(rect.size/to_screen_rect.size); - } - } else { + if (to_screen_rect!=Rect2()) { - pre_xf.elements[2]=-rect.pos; + pre_xf.elements[2]=-to_screen_rect.pos; + pre_xf.scale(size/to_screen_rect.size); } return pre_xf; @@ -1356,9 +1340,9 @@ Matrix32 Viewport::_get_input_pre_xform() const { Vector2 Viewport::_get_window_offset() const { - if (parent_control) { - return (parent_control->get_viewport()->get_final_transform() * parent_control->get_global_transform_with_canvas()).get_origin(); - } +// if (parent_control) { +// return (parent_control->get_viewport()->get_final_transform() * parent_control->get_global_transform_with_canvas()).get_origin(); +// } return Vector2(); } @@ -1454,10 +1438,8 @@ void Viewport::_vp_input(const InputEvent& p_ev) { } #endif - if (parent_control && !parent_control->is_visible()) - return; - if (render_target && to_screen_rect==Rect2()) + if (to_screen_rect==Rect2()) return; //if render target, can't get input events //this one handles system input, p_ev are in system coordinates @@ -1480,10 +1462,10 @@ void Viewport::_vp_unhandled_input(const InputEvent& p_ev) { } #endif - if (parent_control && !parent_control->is_visible()) - return; +// if (parent_control && !parent_control->is_visible()) +// return; - if (render_target && to_screen_rect==Rect2()) + if (to_screen_rect==Rect2()) return; //if render target, can't get input events //this one handles system input, p_ev are in system coordinates @@ -2521,17 +2503,18 @@ bool Viewport::is_using_own_world() const { return own_world.is_valid(); } -void Viewport::set_render_target_to_screen_rect(const Rect2& p_rect) { +void Viewport::set_attach_to_screen_rect(const Rect2& p_rect) { + VS::get_singleton()->viewport_attach_to_screen(viewport,p_rect); to_screen_rect=p_rect; - VisualServer::get_singleton()->viewport_set_render_target_to_screen_rect(viewport,to_screen_rect); } -Rect2 Viewport::get_render_target_to_screen_rect() const{ +Rect2 Viewport::get_attach_to_screen_rect() const{ return to_screen_rect; } + void Viewport::set_physics_object_picking(bool p_enable) { physics_object_picking=p_enable; @@ -2553,7 +2536,7 @@ Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const { Vector2 Viewport::get_camera_rect_size() const { - return last_vp_rect.size; + return size; } @@ -2577,6 +2560,16 @@ bool Viewport::is_input_disabled() const { return disable_input; } +void Viewport::set_disable_3d(bool p_disable) { + disable_3d=p_disable; + VS::get_singleton()->viewport_set_disable_3d(viewport,p_disable); +} + +bool Viewport::is_3d_disabled() const { + + return disable_3d; +} + Variant Viewport::gui_get_drag_data() const { return gui.drag_data; } @@ -2587,19 +2580,58 @@ Control *Viewport::get_modal_stack_top() const { String Viewport::get_configuration_warning() const { - if (get_parent() && !get_parent()->cast_to<Control>() && !render_target) { + /*if (get_parent() && !get_parent()->cast_to<Control>() && !render_target) { return TTR("This viewport is not set as render target. If you intend for it to display its contents directly to the screen, make it a child of a Control so it can obtain a size. Otherwise, make it a RenderTarget and assign its internal texture to some node for display."); - } + }*/ return String(); } +void Viewport::gui_reset_canvas_sort_index() { + gui.canvas_sort_index=0; +} +int Viewport::gui_get_canvas_sort_index() { + + return gui.canvas_sort_index++; +} + +void Viewport::set_msaa(MSAA p_msaa) { + + ERR_FAIL_INDEX(p_msaa,5); + if (msaa==p_msaa) + return; + msaa=p_msaa; + VS::get_singleton()->viewport_set_msaa(viewport,VS::ViewportMSAA(p_msaa)); +} + +Viewport::MSAA Viewport::get_msaa() const { + + return msaa; +} + +void Viewport::set_hdr(bool p_hdr) { + + if (hdr==p_hdr) + return; + + hdr=p_hdr; + VS::get_singleton()->viewport_set_hdr(viewport,p_hdr); + +} + +bool Viewport::get_hdr() const{ + + return hdr; +} + + + void Viewport::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_rect","rect"), &Viewport::set_rect); - ObjectTypeDB::bind_method(_MD("get_rect"), &Viewport::get_rect); + ObjectTypeDB::bind_method(_MD("set_size","size"), &Viewport::set_size); + ObjectTypeDB::bind_method(_MD("get_size"), &Viewport::get_size); ObjectTypeDB::bind_method(_MD("set_world_2d","world_2d:World2D"), &Viewport::set_world_2d); ObjectTypeDB::bind_method(_MD("get_world_2d:World2D"), &Viewport::get_world_2d); ObjectTypeDB::bind_method(_MD("find_world_2d:World2D"), &Viewport::find_world_2d); @@ -2633,27 +2665,24 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("queue_screen_capture"), &Viewport::queue_screen_capture); ObjectTypeDB::bind_method(_MD("get_screen_capture"), &Viewport::get_screen_capture); - ObjectTypeDB::bind_method(_MD("set_as_render_target","enable"), &Viewport::set_as_render_target); - ObjectTypeDB::bind_method(_MD("is_set_as_render_target"), &Viewport::is_set_as_render_target); - - ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip); - ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip); - ObjectTypeDB::bind_method(_MD("set_render_target_clear_on_new_frame","enable"), &Viewport::set_render_target_clear_on_new_frame); - ObjectTypeDB::bind_method(_MD("get_render_target_clear_on_new_frame"), &Viewport::get_render_target_clear_on_new_frame); + ObjectTypeDB::bind_method(_MD("set_vflip","enable"), &Viewport::set_vflip); + ObjectTypeDB::bind_method(_MD("get_vflip"), &Viewport::get_vflip); - ObjectTypeDB::bind_method(_MD("render_target_clear"), &Viewport::render_target_clear); + ObjectTypeDB::bind_method(_MD("set_clear_on_new_frame","enable"), &Viewport::set_clear_on_new_frame); + ObjectTypeDB::bind_method(_MD("get_clear_on_new_frame"), &Viewport::get_clear_on_new_frame); - ObjectTypeDB::bind_method(_MD("set_render_target_filter","enable"), &Viewport::set_render_target_filter); - ObjectTypeDB::bind_method(_MD("get_render_target_filter"), &Viewport::get_render_target_filter); + ObjectTypeDB::bind_method(_MD("clear"), &Viewport::clear); + ObjectTypeDB::bind_method(_MD("set_update_mode","mode"), &Viewport::set_update_mode); + ObjectTypeDB::bind_method(_MD("get_update_mode"), &Viewport::get_update_mode); - ObjectTypeDB::bind_method(_MD("set_render_target_gen_mipmaps","enable"), &Viewport::set_render_target_gen_mipmaps); - ObjectTypeDB::bind_method(_MD("get_render_target_gen_mipmaps"), &Viewport::get_render_target_gen_mipmaps); + ObjectTypeDB::bind_method(_MD("set_msaa","msaa"), &Viewport::set_msaa); + ObjectTypeDB::bind_method(_MD("get_msaa"), &Viewport::get_msaa); - ObjectTypeDB::bind_method(_MD("set_render_target_update_mode","mode"), &Viewport::set_render_target_update_mode); - ObjectTypeDB::bind_method(_MD("get_render_target_update_mode"), &Viewport::get_render_target_update_mode); + ObjectTypeDB::bind_method(_MD("set_hdr","enable"), &Viewport::set_hdr); + ObjectTypeDB::bind_method(_MD("get_hdr"), &Viewport::get_hdr); - ObjectTypeDB::bind_method(_MD("get_render_target_texture:RenderTargetTexture"), &Viewport::get_render_target_texture); + ObjectTypeDB::bind_method(_MD("get_texture:ViewportTexture"), &Viewport::get_texture); ObjectTypeDB::bind_method(_MD("set_physics_object_picking","enable"), &Viewport::set_physics_object_picking); ObjectTypeDB::bind_method(_MD("get_physics_object_picking"), &Viewport::get_physics_object_picking); @@ -2674,7 +2703,7 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_as_audio_listener_2d","enable"), &Viewport::set_as_audio_listener_2d); ObjectTypeDB::bind_method(_MD("is_audio_listener_2d","enable"), &Viewport::is_audio_listener_2d); - ObjectTypeDB::bind_method(_MD("set_render_target_to_screen_rect","rect"), &Viewport::set_render_target_to_screen_rect); + ObjectTypeDB::bind_method(_MD("set_attach_to_screen_rect","rect"), &Viewport::set_attach_to_screen_rect); ObjectTypeDB::bind_method(_MD("get_mouse_pos"), &Viewport::get_mouse_pos); ObjectTypeDB::bind_method(_MD("warp_mouse","to_pos"), &Viewport::warp_mouse); @@ -2685,31 +2714,60 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_disable_input","disable"), &Viewport::set_disable_input); ObjectTypeDB::bind_method(_MD("is_input_disabled"), &Viewport::is_input_disabled); + ObjectTypeDB::bind_method(_MD("set_disable_3d","disable"), &Viewport::set_disable_3d); + ObjectTypeDB::bind_method(_MD("is_3d_disabled"), &Viewport::is_3d_disabled); + ObjectTypeDB::bind_method(_MD("_gui_show_tooltip"), &Viewport::_gui_show_tooltip); ObjectTypeDB::bind_method(_MD("_gui_remove_focus"), &Viewport::_gui_remove_focus); - ADD_PROPERTY( PropertyInfo(Variant::RECT2,"rect"), _SCS("set_rect"), _SCS("get_rect") ); + ObjectTypeDB::bind_method(_MD("set_shadow_atlas_size","size"), &Viewport::set_shadow_atlas_size); + ObjectTypeDB::bind_method(_MD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size); + + ObjectTypeDB::bind_method(_MD("set_shadow_atlas_quadrant_subdiv","quadrant","subdiv"), &Viewport::set_shadow_atlas_quadrant_subdiv); + ObjectTypeDB::bind_method(_MD("get_shadow_atlas_quadrant_subdiv","quadrant"), &Viewport::get_shadow_atlas_quadrant_subdiv); + + ADD_PROPERTY( PropertyInfo(Variant::RECT2,"size"), _SCS("set_size"), _SCS("get_size") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"own_world"), _SCS("set_use_own_world"), _SCS("is_using_own_world") ); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world",PROPERTY_HINT_RESOURCE_TYPE,"World"), _SCS("set_world"), _SCS("get_world") ); // ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world_2d",PROPERTY_HINT_RESOURCE_TYPE,"World2D"), _SCS("set_world_2d"), _SCS("get_world_2d") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") ); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") ); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_render_target_vflip"), _SCS("get_render_target_vflip") ); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/clear_on_new_frame"), _SCS("set_render_target_clear_on_new_frame"), _SCS("get_render_target_clear_on_new_frame") ); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/filter"), _SCS("set_render_target_filter"), _SCS("get_render_target_filter") ); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/gen_mipmaps"), _SCS("set_render_target_gen_mipmaps"), _SCS("get_render_target_gen_mipmaps") ); - ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") ); + ADD_PROPERTY( PropertyInfo(Variant::INT,"msaa",PROPERTY_HINT_ENUM,"Disabled,2x,4x,8x,16x"), _SCS("set_msaa"), _SCS("get_msaa") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"hdr"), _SCS("set_hdr"), _SCS("get_hdr") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_vflip"), _SCS("get_vflip") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/clear_on_new_frame"), _SCS("set_clear_on_new_frame"), _SCS("get_clear_on_new_frame") ); + ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_update_mode"), _SCS("get_update_mode") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_2d"), _SCS("set_as_audio_listener_2d"), _SCS("is_audio_listener_2d") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_3d"), _SCS("set_as_audio_listener"), _SCS("is_audio_listener") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"physics/object_picking"), _SCS("set_physics_object_picking"), _SCS("get_physics_object_picking") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gui/disable_input"), _SCS("set_disable_input"), _SCS("is_input_disabled") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"3d/disable_3d"), _SCS("set_disable_3d"), _SCS("is_3d_disabled") ); + ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow_atlas/size"), _SCS("set_shadow_atlas_size"), _SCS("get_shadow_atlas_size") ); + ADD_PROPERTYI( PropertyInfo(Variant::INT,"shadow_atlas/quad_0",PROPERTY_HINT_ENUM,"Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), _SCS("set_shadow_atlas_quadrant_subdiv"), _SCS("get_shadow_atlas_quadrant_subdiv"),0 ); + ADD_PROPERTYI( PropertyInfo(Variant::INT,"shadow_atlas/quad_1",PROPERTY_HINT_ENUM,"Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), _SCS("set_shadow_atlas_quadrant_subdiv"), _SCS("get_shadow_atlas_quadrant_subdiv"),1 ); + ADD_PROPERTYI( PropertyInfo(Variant::INT,"shadow_atlas/quad_2",PROPERTY_HINT_ENUM,"Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), _SCS("set_shadow_atlas_quadrant_subdiv"), _SCS("get_shadow_atlas_quadrant_subdiv"),2 ); + ADD_PROPERTYI( PropertyInfo(Variant::INT,"shadow_atlas/quad_3",PROPERTY_HINT_ENUM,"Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), _SCS("set_shadow_atlas_quadrant_subdiv"), _SCS("get_shadow_atlas_quadrant_subdiv"),3 ); ADD_SIGNAL(MethodInfo("size_changed")); - BIND_CONSTANT( RENDER_TARGET_UPDATE_DISABLED ); - BIND_CONSTANT( RENDER_TARGET_UPDATE_ONCE ); - BIND_CONSTANT( RENDER_TARGET_UPDATE_WHEN_VISIBLE ); - BIND_CONSTANT( RENDER_TARGET_UPDATE_ALWAYS ); + BIND_CONSTANT( UPDATE_DISABLED ); + BIND_CONSTANT( UPDATE_ONCE ); + BIND_CONSTANT( UPDATE_WHEN_VISIBLE ); + BIND_CONSTANT( UPDATE_ALWAYS ); + + BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED ); + BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_1 ); + BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_4 ); + BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_16 ); + BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_64 ); + BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_256 ); + BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_1024 ); + BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_MAX ); + + BIND_CONSTANT( MSAA_DISABLED ); + BIND_CONSTANT( MSAA_2X ); + BIND_CONSTANT( MSAA_4X ); + BIND_CONSTANT( MSAA_8X ); + BIND_CONSTANT( MSAA_16X ); } @@ -2723,6 +2781,7 @@ Viewport::Viewport() { world_2d = Ref<World2D>( memnew( World2D )); viewport = VisualServer::get_singleton()->viewport_create(); + texture_rid=VisualServer::get_singleton()->viewport_get_texture(viewport); internal_listener = SpatialSoundServer::get_singleton()->listener_create(); audio_listener=false; internal_listener_2d = SpatialSound2DServer::get_singleton()->listener_create(); @@ -2734,19 +2793,28 @@ Viewport::Viewport() { size_override=false; size_override_stretch=false; size_override_size=Size2(1,1); - render_target_gen_mipmaps=false; - render_target=false; - render_target_vflip=false; - render_target_clear_on_new_frame=true; - //render_target_clear=true; - render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; - render_target_texture = Ref<RenderTargetTexture>( memnew( RenderTargetTexture(this) ) ); + gen_mipmaps=false; + + vflip=false; + clear_on_new_frame=true; + //clear=true; + update_mode=UPDATE_WHEN_VISIBLE; + texture = Ref<ViewportTexture>( memnew( ViewportTexture(this) ) ); physics_object_picking=false; physics_object_capture=0; physics_object_over=0; physics_last_mousepos=Vector2(1e20,1e20); + shadow_atlas_size=0; + for(int i=0;i<4;i++) { + shadow_atlas_quadrant_subdiv[i]=SHADOW_ATLAS_QUADRANT_SUBDIV_MAX; + } + set_shadow_atlas_quadrant_subdiv(0,SHADOW_ATLAS_QUADRANT_SUBDIV_4); + set_shadow_atlas_quadrant_subdiv(1,SHADOW_ATLAS_QUADRANT_SUBDIV_4); + set_shadow_atlas_quadrant_subdiv(2,SHADOW_ATLAS_QUADRANT_SUBDIV_16); + set_shadow_atlas_quadrant_subdiv(3,SHADOW_ATLAS_QUADRANT_SUBDIV_64); + String id=itos(get_instance_ID()); input_group = "_vp_input"+id; @@ -2755,6 +2823,7 @@ Viewport::Viewport() { unhandled_key_input_group = "_vp_unhandled_key_input"+id; disable_input=false; + disable_3d=false; //window tooltip gui.tooltip_timer = -1; @@ -2766,9 +2835,11 @@ Viewport::Viewport() { gui.tooltip_label=NULL; gui.drag_preview=NULL; gui.drag_attempted=false; + gui.canvas_sort_index=0; - parent_control=NULL; + msaa=MSAA_DISABLED; + hdr=false; } @@ -2779,8 +2850,8 @@ Viewport::~Viewport() { VisualServer::get_singleton()->free( viewport ); SpatialSoundServer::get_singleton()->free(internal_listener); SpatialSound2DServer::get_singleton()->free(internal_listener_2d); - if (render_target_texture.is_valid()) - render_target_texture->vp=NULL; //so if used, will crash + if (texture.is_valid()) + texture->vp=NULL; //so if used, will crash } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 2a54aec96a..c4b4948c30 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -48,9 +48,9 @@ class Label; class Timer; class Viewport; -class RenderTargetTexture : public Texture { +class ViewportTexture : public Texture { - OBJ_TYPE( RenderTargetTexture, Texture ); + OBJ_TYPE( ViewportTexture, Texture ); int flags; friend class Viewport; @@ -70,7 +70,7 @@ public: virtual void set_flags(uint32_t p_flags); virtual uint32_t get_flags() const; - RenderTargetTexture(Viewport *p_vp=NULL); + ViewportTexture(Viewport *p_vp=NULL); }; @@ -79,19 +79,39 @@ class Viewport : public Node { OBJ_TYPE( Viewport, Node ); public: - enum RenderTargetUpdateMode { - RENDER_TARGET_UPDATE_DISABLED, - RENDER_TARGET_UPDATE_ONCE, //then goes to disabled - RENDER_TARGET_UPDATE_WHEN_VISIBLE, // default - RENDER_TARGET_UPDATE_ALWAYS + enum UpdateMode { + UPDATE_DISABLED, + UPDATE_ONCE, //then goes to disabled + UPDATE_WHEN_VISIBLE, // default + UPDATE_ALWAYS + }; + + enum ShadowAtlasQuadrantSubdiv { + SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED, + SHADOW_ATLAS_QUADRANT_SUBDIV_1, + SHADOW_ATLAS_QUADRANT_SUBDIV_4, + SHADOW_ATLAS_QUADRANT_SUBDIV_16, + SHADOW_ATLAS_QUADRANT_SUBDIV_64, + SHADOW_ATLAS_QUADRANT_SUBDIV_256, + SHADOW_ATLAS_QUADRANT_SUBDIV_1024, + SHADOW_ATLAS_QUADRANT_SUBDIV_MAX, + + }; + + enum MSAA { + MSAA_DISABLED, + MSAA_2X, + MSAA_4X, + MSAA_8X, + MSAA_16X, }; private: -friend class RenderTargetTexture; +friend class ViewportTexture; + - Control *parent_control; Viewport *parent; Listener *listener; @@ -101,7 +121,6 @@ friend class RenderTargetTexture; Set<Camera*> cameras; RID viewport; - RID canvas_item; RID current_canvas; bool audio_listener; @@ -114,15 +133,13 @@ friend class RenderTargetTexture; Matrix32 global_canvas_transform; Matrix32 stretch_transform; - Rect2 rect; + Size2 size; Rect2 to_screen_rect; RID contact_2d_debug; RID contact_3d_debug_multimesh; RID contact_3d_debug_instance; - - bool size_override; bool size_override_stretch; Size2 size_override_size; @@ -131,10 +148,10 @@ friend class RenderTargetTexture; Rect2 last_vp_rect; bool transparent_bg; - bool render_target_vflip; - bool render_target_clear_on_new_frame; - bool render_target_filter; - bool render_target_gen_mipmaps; + bool vflip; + bool clear_on_new_frame; + bool filter; + bool gen_mipmaps; bool physics_object_picking; List<InputEvent> physics_picking_events; @@ -170,10 +187,17 @@ friend class RenderTargetTexture; void _update_stretch_transform(); void _update_global_transform(); - bool render_target; - RenderTargetUpdateMode render_target_update_mode; - RID render_target_texture_rid; - Ref<RenderTargetTexture> render_target_texture; + + bool disable_3d; + UpdateMode update_mode; + RID texture_rid; + Ref<ViewportTexture> texture; + + int shadow_atlas_size; + ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4]; + + MSAA msaa; + bool hdr; struct GUI { @@ -202,6 +226,7 @@ friend class RenderTargetTexture; List<Control*> subwindows; bool roots_order_dirty; List<Control*> roots; + int canvas_sort_index; //for sorting items with canvas as root GUI(); @@ -299,8 +324,10 @@ public: void set_as_audio_listener_2d(bool p_enable); bool is_audio_listener_2d() const; - void set_rect(const Rect2& p_rect); - Rect2 get_rect() const; + void set_size(const Size2& p_size); + + + Size2 get_size() const; Rect2 get_visible_rect() const; RID get_viewport() const; @@ -327,30 +354,34 @@ public: void set_size_override(bool p_enable,const Size2& p_size=Size2(-1,-1),const Vector2& p_margin=Vector2()); Size2 get_size_override() const; + bool is_size_override_enabled() const; void set_size_override_stretch(bool p_enable); bool is_size_override_stretch_enabled() const; - void set_as_render_target(bool p_enable); - bool is_set_as_render_target() const; + void set_vflip(bool p_enable); + bool get_vflip() const; + + void set_clear_on_new_frame(bool p_enable); + bool get_clear_on_new_frame() const; + void clear(); - void set_render_target_vflip(bool p_enable); - bool get_render_target_vflip() const; - void set_render_target_clear_on_new_frame(bool p_enable); - bool get_render_target_clear_on_new_frame() const; - void render_target_clear(); + void set_update_mode(UpdateMode p_mode); + UpdateMode get_update_mode() const; + Ref<ViewportTexture> get_texture() const; - void set_render_target_filter(bool p_enable); - bool get_render_target_filter() const; + void set_shadow_atlas_size(int p_size); + int get_shadow_atlas_size() const; - void set_render_target_gen_mipmaps(bool p_enable); - bool get_render_target_gen_mipmaps() const; + void set_shadow_atlas_quadrant_subdiv(int p_quadrant,ShadowAtlasQuadrantSubdiv p_subdiv); + ShadowAtlasQuadrantSubdiv get_shadow_atlas_quadrant_subdiv(int p_quadrant) const; - void set_render_target_update_mode(RenderTargetUpdateMode p_mode); - RenderTargetUpdateMode get_render_target_update_mode() const; - Ref<RenderTargetTexture> get_render_target_texture() const; + void set_msaa(MSAA p_msaa); + MSAA get_msaa() const; + void set_hdr(bool p_hdr); + bool get_hdr() const; Vector2 get_camera_coords(const Vector2& p_viewport_coords) const; Vector2 get_camera_rect_size() const; @@ -367,8 +398,11 @@ public: void set_disable_input(bool p_disable); bool is_input_disabled() const; - void set_render_target_to_screen_rect(const Rect2& p_rect); - Rect2 get_render_target_to_screen_rect() const; + void set_disable_3d(bool p_disable); + bool is_3d_disabled() const; + + void set_attach_to_screen_rect(const Rect2& p_rect); + Rect2 get_attach_to_screen_rect() const; Vector2 get_mouse_pos() const; void warp_mouse(const Vector2& p_pos); @@ -381,12 +415,20 @@ public: Variant gui_get_drag_data() const; Control *get_modal_stack_top() const; + void gui_reset_canvas_sort_index(); + int gui_get_canvas_sort_index(); + virtual String get_configuration_warning() const; + + Viewport(); ~Viewport(); }; -VARIANT_ENUM_CAST(Viewport::RenderTargetUpdateMode); +VARIANT_ENUM_CAST( Viewport::UpdateMode ); +VARIANT_ENUM_CAST( Viewport::ShadowAtlasQuadrantSubdiv ); +VARIANT_ENUM_CAST( Viewport::MSAA ); + #endif diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index f797aa1aca..5cc71d5203 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -66,6 +66,7 @@ #include "scene/gui/center_container.h" #include "scene/gui/scroll_container.h" #include "scene/gui/margin_container.h" +#include "scene/gui/viewport_container.h" #include "scene/gui/panel.h" #include "scene/gui/spin_box.h" #include "scene/gui/file_dialog.h" @@ -165,6 +166,7 @@ #include "scene/resources/sample.h" #include "scene/audio/sample_player.h" #include "scene/resources/texture.h" +#include "scene/resources/sky_box.h" #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "scene/resources/room.h" @@ -202,6 +204,8 @@ #include "scene/3d/mesh_instance.h" #include "scene/3d/quad.h" #include "scene/3d/light.h" +#include "scene/3d/reflection_probe.h" +#include "scene/3d/gi_probe.h" #include "scene/3d/particles.h" #include "scene/3d/portal.h" #include "scene/resources/environment.h" @@ -235,7 +239,6 @@ static ResourceFormatLoaderWAV *resource_loader_wav=NULL; #endif static ResourceFormatLoaderTheme *resource_loader_theme=NULL; -static ResourceFormatLoaderShader *resource_loader_shader=NULL; static ResourceFormatSaverText *resource_saver_text=NULL; static ResourceFormatLoaderText *resource_loader_text=NULL; @@ -269,8 +272,6 @@ void register_scene_types() { resource_loader_theme = memnew( ResourceFormatLoaderTheme ); ResourceLoader::add_resource_format_loader( resource_loader_theme ); - resource_loader_shader = memnew( ResourceFormatLoaderShader ); - ResourceLoader::add_resource_format_loader( resource_loader_shader ); bool default_theme_hidpi=GLOBAL_DEF("display/use_hidpi_theme",false); Globals::get_singleton()->set_custom_property_info("display/use_hidpi_theme",PropertyInfo(Variant::BOOL,"display/use_hidpi_theme",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_RESTART_IF_CHANGED)); @@ -303,7 +304,7 @@ void register_scene_types() { ObjectTypeDB::register_virtual_type<InstancePlaceholder>(); ObjectTypeDB::register_type<Viewport>(); - ObjectTypeDB::register_virtual_type<RenderTargetTexture>(); + ObjectTypeDB::register_type<ViewportTexture>(); ObjectTypeDB::register_type<HTTPRequest>(); ObjectTypeDB::register_type<Timer>(); ObjectTypeDB::register_type<CanvasLayer>(); @@ -393,6 +394,7 @@ void register_scene_types() { ObjectTypeDB::register_type<ConfirmationDialog>(); ObjectTypeDB::register_type<VideoPlayer>(); ObjectTypeDB::register_type<MarginContainer>(); + ObjectTypeDB::register_type<ViewportContainer>(); OS::get_singleton()->yield(); //may take time to init @@ -423,9 +425,12 @@ void register_scene_types() { ObjectTypeDB::register_type<DirectionalLight>(); ObjectTypeDB::register_type<OmniLight>(); ObjectTypeDB::register_type<SpotLight>(); + ObjectTypeDB::register_type<ReflectionProbe>(); + ObjectTypeDB::register_type<GIProbe>(); + ObjectTypeDB::register_type<GIProbeData>(); ObjectTypeDB::register_type<AnimationTreePlayer>(); ObjectTypeDB::register_type<Portal>(); - ObjectTypeDB::register_type<Particles>(); + //ObjectTypeDB::register_type<Particles>(); ObjectTypeDB::register_type<Position3D>(); ObjectTypeDB::register_type<Quad>(); ObjectTypeDB::register_type<NavigationMeshInstance>(); @@ -454,8 +459,8 @@ void register_scene_types() { ObjectTypeDB::register_type<PathFollow>(); ObjectTypeDB::register_type<VisibilityNotifier>(); ObjectTypeDB::register_type<VisibilityEnabler>(); - ObjectTypeDB::register_type<BakedLightInstance>(); - ObjectTypeDB::register_type<BakedLightSampler>(); + ObjectTypeDB::register_type<BakedLight>(); + //ObjectTypeDB::register_type<BakedLightSampler>(); ObjectTypeDB::register_type<WorldEnvironment>(); ObjectTypeDB::register_type<RemoteTransform>(); @@ -490,7 +495,7 @@ void register_scene_types() { ObjectTypeDB::register_type<Particles2D>(); ObjectTypeDB::register_type<ParticleAttractor2D>(); ObjectTypeDB::register_type<Sprite>(); - ObjectTypeDB::register_type<ViewportSprite>(); +// ObjectTypeDB::register_type<ViewportSprite>(); ObjectTypeDB::register_type<SpriteFrames>(); ObjectTypeDB::register_type<AnimatedSprite>(); ObjectTypeDB::register_type<Position2D>(); @@ -539,21 +544,24 @@ void register_scene_types() { /* REGISTER RESOURCES */ ObjectTypeDB::register_virtual_type<Shader>(); - ObjectTypeDB::register_virtual_type<ShaderGraph>(); +// ObjectTypeDB::register_virtual_type<ShaderGraph>(); ObjectTypeDB::register_type<CanvasItemShader>(); - ObjectTypeDB::register_type<CanvasItemShaderGraph>(); +// ObjectTypeDB::register_type<CanvasItemShaderGraph>(); #ifndef _3D_DISABLED ObjectTypeDB::register_type<Mesh>(); ObjectTypeDB::register_virtual_type<Material>(); - ObjectTypeDB::register_type<FixedMaterial>(); - ObjectTypeDB::register_type<ShaderMaterial>(); + ObjectTypeDB::register_type<FixedSpatialMaterial>(); + SceneTree::add_idle_callback(FixedSpatialMaterial::flush_changes); + FixedSpatialMaterial::init_shaders(); +// ObjectTypeDB::register_type<ShaderMaterial>(); ObjectTypeDB::register_type<RoomBounds>(); - ObjectTypeDB::register_type<MaterialShaderGraph>(); - ObjectTypeDB::register_type<MaterialShader>(); +// ObjectTypeDB::register_type<MaterialShaderGraph>(); + ObjectTypeDB::register_type<SpatialShader>(); + ObjectTypeDB::register_type<ParticlesShader>(); ObjectTypeDB::add_compatibility_type("Shader","MaterialShader"); - ObjectTypeDB::add_compatibility_type("ParticleSystemMaterial","FixedMaterial"); - ObjectTypeDB::add_compatibility_type("UnshadedMaterial","FixedMaterial"); + ObjectTypeDB::add_compatibility_type("ParticleSystemMaterial","FixedSpatialMaterial"); + ObjectTypeDB::add_compatibility_type("UnshadedMaterial","FixedSpatialMaterial"); ObjectTypeDB::register_type<MultiMesh>(); ObjectTypeDB::register_type<MeshLibrary>(); @@ -569,7 +577,7 @@ void register_scene_types() { ObjectTypeDB::register_type<SurfaceTool>(); ObjectTypeDB::register_type<MeshDataTool>(); - ObjectTypeDB::register_type<BakedLight>(); + //ObjectTypeDB::register_type<BakedLight>(); OS::get_singleton()->yield(); //may take time to init @@ -578,6 +586,8 @@ void register_scene_types() { ObjectTypeDB::register_type<Environment>(); ObjectTypeDB::register_type<World2D>(); ObjectTypeDB::register_virtual_type<Texture>(); + ObjectTypeDB::register_virtual_type<SkyBox>(); + ObjectTypeDB::register_type<ImageSkyBox>(); ObjectTypeDB::register_type<ImageTexture>(); ObjectTypeDB::register_type<AtlasTexture>(); ObjectTypeDB::register_type<LargeTexture>(); @@ -591,8 +601,7 @@ void register_scene_types() { ObjectTypeDB::register_type<StyleBoxEmpty>(); ObjectTypeDB::register_type<StyleBoxTexture>(); - ObjectTypeDB::register_type<StyleBoxFlat>(); - ObjectTypeDB::register_type<StyleBoxImageMask>(); + ObjectTypeDB::register_type<StyleBoxFlat>(); ObjectTypeDB::register_type<Theme>(); ObjectTypeDB::add_compatibility_type("Font","BitmapFont"); @@ -658,6 +667,7 @@ void unregister_scene_types() { memdelete( resource_loader_wav ); memdelete( resource_loader_dynamic_font ); + #ifdef TOOLS_ENABLED @@ -665,7 +675,6 @@ void unregister_scene_types() { memdelete( resource_loader_theme ); - memdelete( resource_loader_shader ); if (resource_saver_text) { memdelete(resource_saver_text); @@ -673,5 +682,7 @@ void unregister_scene_types() { if (resource_loader_text) { memdelete(resource_loader_text); } + + FixedSpatialMaterial::finish_shaders(); SceneStringNames::free(); } diff --git a/scene/resources/baked_light.cpp b/scene/resources/baked_light.cpp index bcfcbb2170..616c12e8d7 100644 --- a/scene/resources/baked_light.cpp +++ b/scene/resources/baked_light.cpp @@ -29,574 +29,3 @@ #include "baked_light.h" #include "servers/visual_server.h" -void BakedLight::set_mode(Mode p_mode) { - - mode=p_mode; - VS::get_singleton()->baked_light_set_mode(baked_light,(VS::BakedLightMode(p_mode))); - -} - -BakedLight::Mode BakedLight::get_mode() const{ - - return mode; -} - -void BakedLight::set_octree(const DVector<uint8_t>& p_octree) { - - VS::get_singleton()->baked_light_set_octree(baked_light,p_octree); -} - -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); -} - - - - - -void BakedLight::add_lightmap(const Ref<Texture> &p_texture,Size2 p_gen_size) { - - LightMap lm; - lm.texture=p_texture; - lm.gen_size=p_gen_size; - lightmaps.push_back(lm); - _update_lightmaps(); - _change_notify(); -} - -void BakedLight::set_lightmap_gen_size(int p_idx,const Size2& p_size){ - - ERR_FAIL_INDEX(p_idx,lightmaps.size()); - lightmaps[p_idx].gen_size=p_size; - _update_lightmaps(); -} -Size2 BakedLight::get_lightmap_gen_size(int p_idx) const{ - - ERR_FAIL_INDEX_V(p_idx,lightmaps.size(),Size2()); - return lightmaps[p_idx].gen_size; - -} -void BakedLight::set_lightmap_texture(int p_idx,const Ref<Texture> &p_texture){ - - ERR_FAIL_INDEX(p_idx,lightmaps.size()); - lightmaps[p_idx].texture=p_texture; - _update_lightmaps(); - -} -Ref<Texture> BakedLight::get_lightmap_texture(int p_idx) const{ - - ERR_FAIL_INDEX_V(p_idx,lightmaps.size(),Ref<Texture>()); - return lightmaps[p_idx].texture; - -} -void BakedLight::erase_lightmap(int p_idx){ - - ERR_FAIL_INDEX(p_idx,lightmaps.size()); - lightmaps.remove(p_idx); - _update_lightmaps(); - _change_notify(); - -} -int BakedLight::get_lightmaps_count() const{ - - return lightmaps.size(); -} -void BakedLight::clear_lightmaps(){ - - lightmaps.clear(); - _update_lightmaps(); - _change_notify(); -} - - - -void BakedLight::_update_lightmaps() { - - VS::get_singleton()->baked_light_clear_lightmaps(baked_light); - for(int i=0;i<lightmaps.size();i++) { - - RID tid; - if (lightmaps[i].texture.is_valid()) - tid=lightmaps[i].texture->get_rid(); - VS::get_singleton()->baked_light_add_lightmap(baked_light,tid,i); - } -} - - - -RID BakedLight::get_rid() const { - - return baked_light; -} - -Array BakedLight::_get_lightmap_data() const { - - Array ret; - ret.resize(lightmaps.size()*2); - - int idx=0; - for(int i=0;i<lightmaps.size();i++) { - - ret[idx++]=Size2(lightmaps[i].gen_size); - ret[idx++]=lightmaps[i].texture; - } - return ret; - -} - -void BakedLight::_set_lightmap_data(Array p_array){ - - lightmaps.clear(); - for(int i=0;i<p_array.size();i+=2) { - - Size2 size = p_array[i]; - Ref<Texture> tex = p_array[i+1]; -// ERR_CONTINUE(tex.is_null()); - LightMap lm; - lm.gen_size=size; - lm.texture=tex; - lightmaps.push_back(lm); - } - _update_lightmaps(); -} - - -void BakedLight::set_cell_subdivision(int p_subdiv) { - - cell_subdiv=p_subdiv; -} - -int BakedLight::get_cell_subdivision() const{ - - return cell_subdiv; -} - -void BakedLight::set_initial_lattice_subdiv(int p_size){ - - lattice_subdiv=p_size; -} -int BakedLight::get_initial_lattice_subdiv() const{ - - return lattice_subdiv; -} - -void BakedLight::set_plot_size(float p_size){ - - plot_size=p_size; -} -float BakedLight::get_plot_size() const{ - - return plot_size; -} - -void BakedLight::set_bounces(int p_size){ - - bounces=p_size; -} -int BakedLight::get_bounces() const{ - - return bounces; -} - -void BakedLight::set_cell_extra_margin(float p_margin) { - cell_extra_margin=p_margin; -} - -float BakedLight::get_cell_extra_margin() const { - - return cell_extra_margin; -} - -void BakedLight::set_edge_damp(float p_margin) { - edge_damp=p_margin; -} - -float BakedLight::get_edge_damp() const { - - return edge_damp; -} - - -void BakedLight::set_normal_damp(float p_margin) { - normal_damp=p_margin; -} - -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_realtime_color_enabled(const bool p_realtime_color_enabled) { - - VS::get_singleton()->baked_light_set_realtime_color_enabled(baked_light, p_realtime_color_enabled); -} - -bool BakedLight::get_realtime_color_enabled() const { - - return VS::get_singleton()->baked_light_get_realtime_color_enabled(baked_light); -} - - -void BakedLight::set_realtime_color(const Color &p_realtime_color) { - - VS::get_singleton()->baked_light_set_realtime_color(baked_light, p_realtime_color); -} - -Color BakedLight::get_realtime_color() const { - - return VS::get_singleton()->baked_light_get_realtime_color(baked_light); -} - -void BakedLight::set_realtime_energy(const float p_realtime_energy) { - - VS::get_singleton()->baked_light_set_realtime_energy(baked_light, p_realtime_energy); -} - -float BakedLight::get_realtime_energy() const { - - return VS::get_singleton()->baked_light_get_realtime_energy(baked_light); -} - - - -void BakedLight::set_energy_multiplier(float p_multiplier){ - - energy_multiply=p_multiplier; -} -float BakedLight::get_energy_multiplier() const{ - - return energy_multiply; -} - -void BakedLight::set_gamma_adjust(float p_adjust){ - - gamma_adjust=p_adjust; -} -float BakedLight::get_gamma_adjust() const{ - - return gamma_adjust; -} - -void BakedLight::set_bake_flag(BakeFlags p_flags,bool p_enable){ - - flags[p_flags]=p_enable; -} -bool BakedLight::get_bake_flag(BakeFlags p_flags) const{ - - return flags[p_flags]; -} - -void BakedLight::set_format(Format p_format) { - - format=p_format; - VS::get_singleton()->baked_light_set_lightmap_multiplier(baked_light,format==FORMAT_HDR8?8.0:1.0); -} - -BakedLight::Format BakedLight::get_format() const{ - - return format; -} - -void BakedLight::set_transfer_lightmaps_only_to_uv2(bool p_enable) { - - transfer_only_uv2=p_enable; -} - -bool BakedLight::get_transfer_lightmaps_only_to_uv2() const{ - - return transfer_only_uv2; -} - - -bool BakedLight::_set(const StringName& p_name, const Variant& p_value) { - - String n = p_name; - if (!n.begins_with("lightmap")) - return false; - int idx = n.get_slicec('/',1).to_int(); - ERR_FAIL_COND_V(idx<0,false); - ERR_FAIL_COND_V(idx>lightmaps.size(),false); - - String what = n.get_slicec('/',2); - Ref<Texture> tex; - Size2 gens; - - if (what=="texture") - tex=p_value; - else if (what=="gen_size") - gens=p_value; - - if (idx==lightmaps.size()) { - if (tex.is_valid() || gens!=Size2()) - add_lightmap(tex,gens); - } else { - if (tex.is_valid()) - set_lightmap_texture(idx,tex); - else if (gens!=Size2()) - set_lightmap_gen_size(idx,gens); - } - - - return true; -} - -bool BakedLight::_get(const StringName& p_name,Variant &r_ret) const{ - - String n = p_name; - if (!n.begins_with("lightmap")) - return false; - int idx = n.get_slicec('/',1).to_int(); - ERR_FAIL_COND_V(idx<0,false); - ERR_FAIL_COND_V(idx>lightmaps.size(),false); - - String what = n.get_slicec('/',2); - - if (what=="texture") { - if (idx==lightmaps.size()) - r_ret=Ref<Texture>(); - else - r_ret=lightmaps[idx].texture; - - } else if (what=="gen_size") { - - if (idx==lightmaps.size()) - r_ret=Size2(); - else - r_ret=Size2(lightmaps[idx].gen_size); - } else - return false; - - return true; - - -} -void BakedLight::_get_property_list( List<PropertyInfo> *p_list) const{ - - for(int i=0;i<=lightmaps.size();i++) { - - p_list->push_back(PropertyInfo(Variant::VECTOR2,"lightmaps/"+itos(i)+"/gen_size",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR)); - p_list->push_back(PropertyInfo(Variant::OBJECT,"lightmaps/"+itos(i)+"/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture",PROPERTY_USAGE_EDITOR)); - } -} - - -void BakedLight::_bind_methods(){ - - - ObjectTypeDB::bind_method(_MD("set_mode","mode"),&BakedLight::set_mode); - ObjectTypeDB::bind_method(_MD("get_mode"),&BakedLight::get_mode); - - 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); - - ObjectTypeDB::bind_method(_MD("_set_lightmap_data","lightmap_data"),&BakedLight::_set_lightmap_data); - ObjectTypeDB::bind_method(_MD("_get_lightmap_data"),&BakedLight::_get_lightmap_data); - - ObjectTypeDB::bind_method(_MD("set_cell_subdivision","cell_subdivision"),&BakedLight::set_cell_subdivision); - ObjectTypeDB::bind_method(_MD("get_cell_subdivision"),&BakedLight::get_cell_subdivision); - - ObjectTypeDB::bind_method(_MD("set_initial_lattice_subdiv","cell_subdivision"),&BakedLight::set_initial_lattice_subdiv); - ObjectTypeDB::bind_method(_MD("get_initial_lattice_subdiv","cell_subdivision"),&BakedLight::get_initial_lattice_subdiv); - - ObjectTypeDB::bind_method(_MD("set_plot_size","plot_size"),&BakedLight::set_plot_size); - ObjectTypeDB::bind_method(_MD("get_plot_size"),&BakedLight::get_plot_size); - - ObjectTypeDB::bind_method(_MD("set_bounces","bounces"),&BakedLight::set_bounces); - ObjectTypeDB::bind_method(_MD("get_bounces"),&BakedLight::get_bounces); - - ObjectTypeDB::bind_method(_MD("set_cell_extra_margin","cell_extra_margin"),&BakedLight::set_cell_extra_margin); - ObjectTypeDB::bind_method(_MD("get_cell_extra_margin"),&BakedLight::get_cell_extra_margin); - - ObjectTypeDB::bind_method(_MD("set_edge_damp","edge_damp"),&BakedLight::set_edge_damp); - ObjectTypeDB::bind_method(_MD("get_edge_damp"),&BakedLight::get_edge_damp); - - 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_realtime_color_enabled", "enabled"), &BakedLight::set_realtime_color_enabled); - ObjectTypeDB::bind_method(_MD("get_realtime_color_enabled"), &BakedLight::get_realtime_color_enabled); - - ObjectTypeDB::bind_method(_MD("set_realtime_color", "tint"), &BakedLight::set_realtime_color); - ObjectTypeDB::bind_method(_MD("get_realtime_color"), &BakedLight::get_realtime_color); - - ObjectTypeDB::bind_method(_MD("set_realtime_energy", "energy"), &BakedLight::set_realtime_energy); - ObjectTypeDB::bind_method(_MD("get_realtime_energy"), &BakedLight::get_realtime_energy); - - ObjectTypeDB::bind_method(_MD("set_format","format"),&BakedLight::set_format); - ObjectTypeDB::bind_method(_MD("get_format"),&BakedLight::get_format); - - ObjectTypeDB::bind_method(_MD("set_transfer_lightmaps_only_to_uv2","enable"),&BakedLight::set_transfer_lightmaps_only_to_uv2); - ObjectTypeDB::bind_method(_MD("get_transfer_lightmaps_only_to_uv2"),&BakedLight::get_transfer_lightmaps_only_to_uv2); - - - - - ObjectTypeDB::bind_method(_MD("set_energy_multiplier","energy_multiplier"),&BakedLight::set_energy_multiplier); - ObjectTypeDB::bind_method(_MD("get_energy_multiplier"),&BakedLight::get_energy_multiplier); - - ObjectTypeDB::bind_method(_MD("set_gamma_adjust","gamma_adjust"),&BakedLight::set_gamma_adjust); - ObjectTypeDB::bind_method(_MD("get_gamma_adjust"),&BakedLight::get_gamma_adjust); - - ObjectTypeDB::bind_method(_MD("set_bake_flag","flag","enabled"),&BakedLight::set_bake_flag); - ObjectTypeDB::bind_method(_MD("get_bake_flag","flag"),&BakedLight::get_bake_flag); - - ADD_PROPERTY( PropertyInfo(Variant::INT,"mode/mode",PROPERTY_HINT_ENUM,"Octree,Lightmaps"),_SCS("set_mode"),_SCS("get_mode")); - - ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/format",PROPERTY_HINT_ENUM,"RGB,HDR8,HDR16"),_SCS("set_format"),_SCS("get_format")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/cell_subdiv",PROPERTY_HINT_RANGE,"4,14,1"),_SCS("set_cell_subdivision"),_SCS("get_cell_subdivision")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/lattice_subdiv",PROPERTY_HINT_RANGE,"1,5,1"),_SCS("set_initial_lattice_subdiv"),_SCS("get_initial_lattice_subdiv")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/light_bounces",PROPERTY_HINT_RANGE,"0,3,1"),_SCS("set_bounces"),_SCS("get_bounces")); - 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")); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "realtime/enabled"), _SCS("set_realtime_color_enabled"), _SCS("get_realtime_color_enabled")); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "realtime/color", PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_realtime_color"), _SCS("get_realtime_color")); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "realtime/energy", PROPERTY_HINT_RANGE, "0.01,4096.0,0.01"), _SCS("set_realtime_energy"), _SCS("get_realtime_energy")); - - - BIND_CONSTANT( MODE_OCTREE ); - BIND_CONSTANT( MODE_LIGHTMAPS ); - - BIND_CONSTANT( BAKE_DIFFUSE ); - BIND_CONSTANT( BAKE_SPECULAR ); - BIND_CONSTANT( BAKE_TRANSLUCENT ); - BIND_CONSTANT( BAKE_CONSERVE_ENERGY ); - BIND_CONSTANT( BAKE_MAX ); - - -} - - -BakedLight::BakedLight() { - - cell_subdiv=8; - lattice_subdiv=4; - plot_size=2.5; - bounces=1; - 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(); -} - -BakedLight::~BakedLight() { - - VS::get_singleton()->free(baked_light); -} diff --git a/scene/resources/baked_light.h b/scene/resources/baked_light.h index adbe7cccad..0c69ce429e 100644 --- a/scene/resources/baked_light.h +++ b/scene/resources/baked_light.h @@ -32,168 +32,6 @@ #include "resource.h" #include "scene/resources/texture.h" -class BakedLight : public Resource { - OBJ_TYPE( BakedLight, Resource); -public: - enum Mode { - - MODE_OCTREE, - MODE_LIGHTMAPS - }; - - enum Format { - - FORMAT_RGB, - FORMAT_HDR8, - FORMAT_HDR16 - }; - - enum BakeFlags { - BAKE_DIFFUSE, - BAKE_SPECULAR, - BAKE_TRANSLUCENT, - BAKE_CONSERVE_ENERGY, - BAKE_LINEAR_COLOR, - BAKE_MAX - }; - -private: - - RID baked_light; - Mode mode; - struct LightMap { - Size2i gen_size; - Ref<Texture> texture; - }; - - - Vector< LightMap> lightmaps; - - //bake vars - int cell_subdiv; - int lattice_subdiv; - float plot_size; - float energy_multiply; - float gamma_adjust; - 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; - bool flags[BAKE_MAX]; - - - - void _update_lightmaps(); - - Array _get_lightmap_data() const; - void _set_lightmap_data(Array p_array); - -protected: - - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List<PropertyInfo> *p_list) const; - - static void _bind_methods(); - -public: - - void set_cell_subdivision(int p_subdiv); - int get_cell_subdivision() const; - - void set_initial_lattice_subdiv(int p_size); - int get_initial_lattice_subdiv() const; - - void set_plot_size(float p_size); - float get_plot_size() const; - - void set_bounces(int p_size); - int get_bounces() const; - - void set_energy_multiplier(float p_multiplier); - float get_energy_multiplier() const; - - void set_gamma_adjust(float p_adjust); - float get_gamma_adjust() const; - - void set_cell_extra_margin(float p_margin); - float get_cell_extra_margin() const; - - void set_edge_damp(float p_margin); - float get_edge_damp() const; - - 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_realtime_color_enabled(const bool p_enabled); - bool get_realtime_color_enabled() const; - - void set_realtime_color(const Color& p_realtime_color); - Color get_realtime_color() const; - - void set_realtime_energy(const float p_realtime_energy); - float get_realtime_energy() const; - - void set_bake_flag(BakeFlags p_flags,bool p_enable); - bool get_bake_flag(BakeFlags p_flags) const; - - void set_format(Format p_margin); - Format get_format() const; - - void set_transfer_lightmaps_only_to_uv2(bool p_enable); - bool get_transfer_lightmaps_only_to_uv2() const; - - void set_mode(Mode p_mode); - Mode get_mode() const; - - 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; - void set_lightmap_texture(int p_idx,const Ref<Texture> &p_texture); - Ref<Texture> get_lightmap_texture(int p_idx) const; - void erase_lightmap(int p_idx); - int get_lightmaps_count() const; - void clear_lightmaps(); - - virtual RID get_rid() const; - - BakedLight(); - ~BakedLight(); -}; - - -VARIANT_ENUM_CAST(BakedLight::Format); -VARIANT_ENUM_CAST(BakedLight::Mode); -VARIANT_ENUM_CAST(BakedLight::BakeFlags); #endif // BAKED_LIGHT_H diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp index b9b31ba32a..5763be2e08 100644 --- a/scene/resources/bit_mask.cpp +++ b/scene/resources/bit_mask.cpp @@ -45,8 +45,8 @@ void BitMap::create_from_image_alpha(const Image& p_image){ ERR_FAIL_COND(p_image.empty()); Image img=p_image; - img.convert(Image::FORMAT_INTENSITY); - ERR_FAIL_COND(img.get_format()!=Image::FORMAT_INTENSITY); + img.convert(Image::FORMAT_LA8); + ERR_FAIL_COND(img.get_format()!=Image::FORMAT_LA8); create(Size2(img.get_width(),img.get_height())); @@ -58,7 +58,7 @@ void BitMap::create_from_image_alpha(const Image& p_image){ int bbyte = i/8; int bbit = i % 8; - if (r[i]) + if (r[i*2]) w[bbyte]|=(1<<bbit); } @@ -193,7 +193,6 @@ void BitMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY,"data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_data"),_SCS("_get_data")); - } BitMap::BitMap() { diff --git a/scene/resources/default_theme/color_picker_hue.png b/scene/resources/default_theme/color_picker_hue.png Binary files differnew file mode 100644 index 0000000000..9bdd24f4fe --- /dev/null +++ b/scene/resources/default_theme/color_picker_hue.png diff --git a/scene/resources/default_theme/color_picker_main.png b/scene/resources/default_theme/color_picker_main.png Binary files differnew file mode 100644 index 0000000000..0498628180 --- /dev/null +++ b/scene/resources/default_theme/color_picker_main.png diff --git a/scene/resources/default_theme/color_picker_sample.png b/scene/resources/default_theme/color_picker_sample.png Binary files differnew file mode 100644 index 0000000000..b145a3e384 --- /dev/null +++ b/scene/resources/default_theme/color_picker_sample.png diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index d90c66af38..4c6cf1c7c0 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -58,14 +58,14 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src,float p_left, float p_top, flo if (scale>1) { Size2 orig_size = Size2(img.get_width(),img.get_height()); - img.convert(Image::FORMAT_RGBA); + img.convert(Image::FORMAT_RGBA8); img.expand_x2_hq2x(); if (scale!=2.0) { img.resize(orig_size.x*scale,orig_size.y*scale); } } else if (scale<1) { Size2 orig_size = Size2(img.get_width(),img.get_height()); - img.convert(Image::FORMAT_RGBA); + img.convert(Image::FORMAT_RGBA8); img.resize(orig_size.x*scale,orig_size.y*scale); } @@ -108,14 +108,14 @@ static Ref<Texture> make_icon(T p_src) { if (scale>1) { Size2 orig_size = Size2(img.get_width(),img.get_height()); - img.convert(Image::FORMAT_RGBA); + img.convert(Image::FORMAT_RGBA8); img.expand_x2_hq2x(); if (scale!=2.0) { img.resize(orig_size.x*scale,orig_size.y*scale); } } else if (scale<1) { Size2 orig_size = Size2(img.get_width(),img.get_height()); - img.convert(Image::FORMAT_RGBA); + img.convert(Image::FORMAT_RGBA8); img.resize(orig_size.x*scale,orig_size.y*scale); } texture->create_from_image( img,ImageTexture::FLAG_FILTER ); @@ -125,7 +125,7 @@ static Ref<Texture> make_icon(T p_src) { static Ref<Shader> make_shader(const char*vertex_code,const char*fragment_code,const char*lighting_code) { Ref<Shader> shader = (memnew( Shader(Shader::MODE_CANVAS_ITEM) )); - shader->set_code(vertex_code, fragment_code, lighting_code); +// shader->set_code(vertex_code, fragment_code, lighting_code); return shader; } @@ -214,6 +214,8 @@ static Ref<StyleBox> make_empty_stylebox(float p_margin_left=-1, float p_margin_ return style; } + + void fill_default_theme(Ref<Theme>& t, const Ref<Font> & default_font, const Ref<Font> & large_font, Ref<Texture>& default_icon, Ref<StyleBox>& default_style, float p_scale) { scale=p_scale; @@ -833,10 +835,15 @@ void fill_default_theme(Ref<Theme>& t, const Ref<Font> & default_font, const Ref t->set_icon("screen_picker","ColorPicker", make_icon( icon_color_pick_png ) ); t->set_icon("add_preset","ColorPicker", make_icon( icon_add_png ) ); + t->set_icon("color_area", "ColorPicker", make_icon( color_picker_main_png)); + t->set_icon("color_hue", "ColorPicker", make_icon( color_picker_hue_png)); + t->set_icon("color_sample", "ColorPicker", make_icon( color_picker_sample_png)); t->set_shader("uv_editor", "ColorPicker", make_shader("", uv_editor_shader_code, "")); t->set_shader("w_editor", "ColorPicker", make_shader("", w_editor_shader_code, "")); + + // TooltipPanel Ref<StyleBoxTexture> style_tt = make_stylebox( tooltip_bg_png,4,4,4,4); @@ -962,7 +969,6 @@ void fill_default_theme(Ref<Theme>& t, const Ref<Font> & default_font, const Ref t->set_icon( "logo","Icons", make_icon(logo_png) ); - // Theme default_icon= make_icon(error_icon_png) ; diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 73c801483f..913ea9b5e9 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -69,6 +69,21 @@ static const unsigned char close_hl_png[]={ }; +static const unsigned char color_picker_hue_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x1,0x0,0x8,0x2,0x0,0x0,0x0,0x35,0x30,0x61,0x19,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x9,0x18,0xc,0x24,0x18,0xa9,0xb3,0x2c,0xb7,0x0,0x0,0x0,0x23,0x49,0x44,0x41,0x54,0x68,0xde,0xed,0xc1,0x31,0x1,0x0,0x0,0x0,0xc2,0xa0,0xf5,0x4f,0x6d,0xd,0xf,0xa0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xbe,0xd,0x31,0x0,0x0,0x1,0x35,0x84,0x14,0xe2,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + +static const unsigned char color_picker_main_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x1,0x0,0x0,0x0,0x1,0x0,0x8,0x2,0x0,0x0,0x0,0xd3,0x10,0x3f,0x31,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x9,0x18,0xc,0x23,0x22,0x20,0xfe,0x63,0xc2,0x0,0x0,0x0,0xd5,0x49,0x44,0x41,0x54,0x78,0xda,0xed,0xc1,0x31,0x1,0x0,0x0,0x0,0xc2,0xa0,0xf5,0x4f,0xed,0x65,0xb,0xa0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x1b,0x1,0x2d,0x0,0x1,0x9e,0xcb,0xc2,0xed,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + +static const unsigned char color_picker_sample_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x14,0x8,0x2,0x0,0x0,0x0,0xed,0x20,0x74,0x8,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x9,0x18,0xc,0x27,0x37,0x29,0x4f,0x42,0x2d,0x0,0x0,0x0,0x61,0x49,0x44,0x41,0x54,0x68,0xde,0xed,0xd9,0xb1,0xd,0x0,0x21,0xc,0x3,0x40,0x40,0xbf,0x5f,0x66,0xcd,0x84,0xf9,0x96,0x19,0xf0,0x5d,0x87,0x5c,0x5b,0x9,0xca,0x9e,0x99,0x75,0xe9,0xee,0xfb,0x59,0x55,0x52,0xe9,0xc3,0xe9,0x59,0x10,0x4c,0x1,0x50,0x0,0x50,0x0,0x8,0xf4,0xf9,0x15,0x49,0x93,0x53,0x13,0x0,0x2b,0x10,0x28,0x0,0x28,0x0,0x64,0xd9,0x2e,0xc1,0xd2,0xe4,0xd4,0x4,0xc0,0xa,0x4,0xa,0x0,0xa,0x0,0x59,0x5c,0x82,0xa5,0xd1,0xa9,0x9,0x80,0x15,0x8,0x14,0x0,0x14,0x0,0xb2,0xfc,0x5b,0xb2,0x3c,0x5a,0x4,0xa1,0xf3,0x57,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + static const unsigned char dosfont_png[]={ 0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x80,0x1,0x0,0x0,0x0,0x0,0xeb,0x45,0x5c,0x66,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1,0x8f,0xb,0xfc,0x61,0x5,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a,0x26,0x0,0x0,0x80,0x84,0x0,0x0,0xfa,0x0,0x0,0x0,0x80,0xe8,0x0,0x0,0x75,0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x70,0x9c,0xba,0x51,0x3c,0x0,0x0,0x0,0x2,0x74,0x52,0x4e,0x53,0x0,0x0,0x76,0x93,0xcd,0x38,0x0,0x0,0x0,0x2,0x62,0x4b,0x47,0x44,0x0,0x1,0xdd,0x8a,0x13,0xa4,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x89,0x0,0x0,0xb,0x89,0x1,0x37,0xc9,0xcb,0xad,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x6,0x16,0x12,0x2b,0x5,0x39,0x1a,0x32,0x39,0x0,0x0,0x2,0x83,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0xd4,0xb1,0x6e,0xdb,0x30,0x10,0x0,0x50,0x22,0x3,0x27,0x22,0xc8,0x78,0x83,0x91,0xa9,0x1f,0xc0,0xa9,0x10,0xa,0x7e,0xc,0x11,0x14,0x87,0xc,0x1c,0x32,0x9,0x1a,0xe,0x46,0xa6,0xfc,0x43,0xff,0x86,0xb5,0x80,0x9b,0x88,0x8e,0x5d,0x64,0x18,0x9e,0xdc,0xd5,0x53,0x91,0xc1,0xa0,0x7a,0xa4,0xe4,0xd4,0x31,0xd2,0x25,0x70,0x97,0xa2,0x37,0x48,0xe6,0x33,0x45,0xdd,0x51,0x24,0x95,0x7a,0x23,0xe0,0x75,0x13,0xb,0xd8,0x93,0xbf,0x51,0x51,0xa3,0xac,0x99,0xc9,0x29,0x87,0x81,0x83,0xb2,0x0,0xc7,0xfe,0xee,0x43,0x58,0x85,0x95,0xb7,0xa6,0xb6,0xaf,0x7a,0xe9,0x93,0x63,0xc3,0xf2,0xc,0x96,0x3e,0xba,0x97,0x11,0x3,0xb5,0x46,0xc0,0x15,0x30,0x43,0x1,0xbd,0x6,0x81,0x71,0xa9,0xb2,0x82,0x9,0x92,0x3d,0xf6,0xb0,0xbd,0x5c,0xf2,0x53,0xf2,0x75,0xc,0x11,0x5f,0xc7,0xe0,0xc4,0xaa,0xb4,0x40,0x41,0xc4,0x69,0xd0,0x27,0x55,0x12,0x13,0x78,0x74,0xa7,0xb5,0xd8,0x3f,0x14,0x77,0x81,0x0,0x22,0x93,0x9b,0x4c,0x54,0x5b,0x72,0x6d,0x98,0x17,0xd1,0x33,0xb3,0x94,0xaa,0x3c,0x93,0xea,0xb4,0x76,0x31,0x6a,0x66,0x0,0xa9,0x59,0x1c,0x8c,0xe,0x33,0xc0,0x12,0x4c,0x29,0xc2,0xa5,0xc3,0xc1,0xd0,0xb2,0x64,0x6a,0x60,0xa3,0xc0,0xea,0xac,0x19,0x58,0x4b,0xa9,0x4a,0x17,0xf0,0xda,0x68,0xb6,0x5,0xec,0xb2,0xf6,0x88,0x33,0xc8,0x18,0x52,0xd5,0x5a,0x1,0xb3,0x61,0x1,0x53,0xdf,0x2,0x51,0x2d,0x33,0xdd,0x12,0x59,0xea,0x94,0x95,0x3c,0x80,0x2e,0x5e,0xf9,0xdb,0x71,0x73,0x70,0xcf,0x39,0x3b,0x76,0xb7,0xbb,0x7d,0xcf,0x74,0x50,0xd,0x62,0x40,0x44,0x6,0x83,0xfe,0xc7,0x8e,0x51,0x5,0x5c,0xe1,0xdd,0xdd,0xaa,0xc2,0xf8,0x53,0x80,0x31,0xe2,0xfd,0x7d,0x14,0x8,0x7e,0xcc,0x5,0x28,0x62,0xd7,0xc5,0xc,0xa6,0xf3,0xc3,0x46,0xa6,0x30,0xd7,0x1e,0x1b,0x2e,0xd0,0x7f,0x63,0x5f,0x1f,0xf1,0x32,0xc9,0x90,0x82,0xef,0xb9,0x82,0xc,0x5a,0x1,0xef,0x66,0x90,0xd7,0x7a,0x2c,0x80,0x13,0x94,0xc4,0xf6,0x9f,0xd8,0x75,0xbb,0x2c,0x89,0xed,0xff,0x42,0xe9,0xa7,0xfb,0xa4,0x84,0xec,0x13,0x45,0x7,0x1a,0xb9,0x97,0x18,0x65,0xab,0x4,0xf9,0x54,0x8c,0x3c,0x54,0xe8,0xed,0xa3,0x7c,0x7b,0x55,0xe0,0x8b,0x0,0xf6,0x4f,0x36,0xd6,0x3d,0xc3,0xe8,0x41,0xc0,0xa1,0xb1,0xdb,0x9,0xa8,0x29,0x0,0xe,0xec,0xc3,0x4,0xc1,0x8,0xc,0x0,0xd6,0x36,0xf3,0x23,0xba,0x80,0x3,0x6f,0x17,0x15,0xbe,0x4b,0xe5,0x8c,0x23,0xc2,0x57,0x7b,0x5d,0x61,0x53,0xc0,0x61,0xf,0xbd,0xd5,0x15,0x68,0x47,0x8e,0x0,0x7b,0x37,0xba,0xab,0xba,0x59,0xcc,0x79,0x3d,0xd7,0xaf,0x5a,0xe3,0x85,0x66,0x69,0xab,0x16,0x32,0x31,0x5b,0xd0,0xdb,0x66,0x2,0x2f,0x6f,0xe,0xb2,0x42,0xb5,0x87,0xdf,0xf0,0x59,0xae,0x6a,0x86,0xae,0x93,0x4c,0x7d,0x1b,0x9a,0x6b,0x84,0xdd,0x9a,0xd6,0xca,0xc8,0x89,0xc3,0xfb,0xd4,0x82,0xe,0x30,0xa2,0x2c,0x18,0xc2,0x98,0xb2,0x4f,0x8,0xba,0x83,0xa1,0x40,0x12,0x88,0x6f,0x43,0x38,0x82,0x1c,0x1f,0x15,0x70,0x82,0x96,0xa8,0xa5,0x3d,0xed,0x9c,0xde,0xb9,0x1,0xe9,0xb8,0x5f,0x4c,0x39,0xd2,0xa6,0xac,0xa6,0x48,0xe7,0xd0,0x95,0x53,0xb0,0xc4,0x7b,0x97,0xd4,0xcd,0x3c,0xdd,0xf0,0xd0,0x4e,0xbf,0xe6,0x65,0x24,0x5b,0x7b,0x7d,0xe,0xe5,0xd6,0xae,0xe9,0x90,0x64,0xfd,0x70,0x9e,0x21,0xb5,0x6c,0x5,0xa4,0xa2,0x87,0xe9,0xa3,0x25,0xf4,0x5,0x5c,0x39,0x61,0xa6,0x1e,0xbe,0x11,0x18,0x80,0xed,0xb,0x18,0x9b,0x70,0x70,0xec,0x5f,0x80,0x3f,0x26,0x27,0xb3,0xc9,0x33,0xc8,0x5c,0x2c,0x5a,0x59,0x1f,0xcb,0x2c,0x89,0x9d,0xae,0xf,0x7d,0xcc,0xdb,0x9c,0xdd,0xd5,0xed,0x7c,0x7f,0xbe,0xd0,0x52,0xf9,0x1f,0xff,0x76,0xfc,0x2,0x24,0x3a,0x65,0x42,0xf6,0x41,0x91,0x95,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x0,0x25,0x74,0x45,0x58,0x74,0x64,0x61,0x74,0x65,0x3a,0x63,0x72,0x65,0x61,0x74,0x65,0x0,0x32,0x30,0x31,0x36,0x2d,0x30,0x36,0x2d,0x32,0x32,0x54,0x32,0x30,0x3a,0x33,0x39,0x3a,0x32,0x36,0x2b,0x30,0x32,0x3a,0x30,0x30,0xc9,0xad,0xc8,0x52,0x0,0x0,0x0,0x25,0x74,0x45,0x58,0x74,0x64,0x61,0x74,0x65,0x3a,0x6d,0x6f,0x64,0x69,0x66,0x79,0x0,0x32,0x30,0x31,0x36,0x2d,0x30,0x36,0x2d,0x32,0x32,0x54,0x32,0x30,0x3a,0x33,0x39,0x3a,0x32,0x36,0x2b,0x30,0x32,0x3a,0x30,0x30,0xb8,0xf0,0x70,0xee,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 3361c1e41c..b661240fd3 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -573,7 +573,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) { //blit to image and texture { - Image img(tex.texture_size,tex.texture_size,0,Image::FORMAT_GRAYSCALE_ALPHA,tex.imgdata); + Image img(tex.texture_size,tex.texture_size,0,Image::FORMAT_LA8,tex.imgdata); if (tex.texture.is_null()) { tex.texture.instance(); diff --git a/scene/resources/dynamic_font_stb.cpp b/scene/resources/dynamic_font_stb.cpp index 456e6a5ee7..d1efc0f705 100644 --- a/scene/resources/dynamic_font_stb.cpp +++ b/scene/resources/dynamic_font_stb.cpp @@ -321,7 +321,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) { //blit to image and texture { - Image img(tex.texture_size,tex.texture_size,0,Image::FORMAT_GRAYSCALE_ALPHA,tex.imgdata); + Image img(tex.texture_size,tex.texture_size,0,Image::FORMAT_LA8,tex.imgdata); if (tex.texture.is_null()) { tex.texture.instance(); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index a7b7d291d4..6e388e70ec 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -28,267 +28,1017 @@ /*************************************************************************/ #include "environment.h" #include "texture.h" -void Environment::set_background(BG p_bg) { +#include "globals.h" +#include "servers/visual_server.h" + +RID Environment::get_rid() const { + + return environment; +} + + +void Environment::set_background(BGMode p_bg) { - ERR_FAIL_INDEX(p_bg,BG_MAX); bg_mode=p_bg; VS::get_singleton()->environment_set_background(environment,VS::EnvironmentBG(p_bg)); + _change_notify(); +} + +void Environment::set_skybox(const Ref<SkyBox> &p_skybox){ + + bg_skybox=p_skybox; + + RID sb_rid; + if (bg_skybox.is_valid()) + sb_rid=bg_skybox->get_rid(); + + VS::get_singleton()->environment_set_skybox(environment,sb_rid); +} + +void Environment::set_skybox_scale(float p_scale) { + + bg_skybox_scale=p_scale; + VS::get_singleton()->environment_set_skybox_scale(environment,p_scale); +} + +void Environment::set_bg_color(const Color& p_color){ + + bg_color=p_color; + VS::get_singleton()->environment_set_bg_color(environment,p_color); +} +void Environment::set_bg_energy(float p_energy){ + + bg_energy=p_energy; + VS::get_singleton()->environment_set_bg_energy(environment,p_energy); +} +void Environment::set_canvas_max_layer(int p_max_layer){ + + bg_canvas_max_layer=p_max_layer; + VS::get_singleton()->environment_set_canvas_max_layer(environment,p_max_layer); +} +void Environment::set_ambient_light_color(const Color& p_color){ + + ambient_color=p_color; + VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_contribution); +} +void Environment::set_ambient_light_energy(float p_energy){ + + ambient_energy=p_energy; + VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_contribution); } +void Environment::set_ambient_light_skybox_contribution(float p_energy){ -Environment::BG Environment::get_background() const{ + ambient_skybox_contribution=p_energy; + VS::get_singleton()->environment_set_ambient_light(environment,ambient_color,ambient_energy,ambient_skybox_contribution); +} + +Environment::BGMode Environment::get_background() const{ return bg_mode; } +Ref<SkyBox> Environment::get_skybox() const{ -void Environment::set_background_param(BGParam p_param, const Variant& p_value){ + return bg_skybox; +} - ERR_FAIL_INDEX(p_param,BG_PARAM_MAX); - bg_param[p_param]=p_value; - VS::get_singleton()->environment_set_background_param(environment,VS::EnvironmentBGParam(p_param),p_value); +float Environment::get_skybox_scale() const { + return bg_skybox_scale; } -Variant Environment::get_background_param(BGParam p_param) const{ - ERR_FAIL_INDEX_V(p_param,BG_PARAM_MAX,Variant()); - return bg_param[p_param]; +Color Environment::get_bg_color() const{ + return bg_color; } +float Environment::get_bg_energy() const{ -void Environment::set_enable_fx(Fx p_effect,bool p_enabled){ + return bg_energy; +} +int Environment::get_canvas_max_layer() const{ - ERR_FAIL_INDEX(p_effect,FX_MAX); - fx_enabled[p_effect]=p_enabled; - VS::get_singleton()->environment_set_enable_fx(environment,VS::EnvironmentFx(p_effect),p_enabled); + return bg_canvas_max_layer; +} +Color Environment::get_ambient_light_color() const{ + return ambient_color; } -bool Environment::is_fx_enabled(Fx p_effect) const{ +float Environment::get_ambient_light_energy() const{ - ERR_FAIL_INDEX_V(p_effect,FX_MAX,false); - return fx_enabled[p_effect]; + return ambient_energy; +} +float Environment::get_ambient_light_skybox_contribution() const{ + return ambient_skybox_contribution; } -void Environment::fx_set_param(FxParam p_param,const Variant& p_value){ - ERR_FAIL_INDEX(p_param,FX_PARAM_MAX); - fx_param[p_param]=p_value; - VS::get_singleton()->environment_fx_set_param(environment,VS::EnvironmentFxParam(p_param),p_value); +void Environment::set_tonemapper(ToneMapper p_tone_mapper) { + + tone_mapper=p_tone_mapper; + VS::get_singleton()->environment_set_tonemap(environment,VS::EnvironmentToneMapper(tone_mapper),tonemap_exposure,tonemap_white,tonemap_auto_exposure,tonemap_auto_exposure_min,tonemap_auto_exposure_max,tonemap_auto_exposure_speed,tonemap_auto_exposure_grey); } -Variant Environment::fx_get_param(FxParam p_param) const{ - ERR_FAIL_INDEX_V(p_param,FX_PARAM_MAX,Variant()); - return fx_param[p_param]; +Environment::ToneMapper Environment::get_tonemapper() const{ + return tone_mapper; } -RID Environment::get_rid() const { +void Environment::set_tonemap_exposure(float p_exposure){ + + tonemap_exposure=p_exposure; + VS::get_singleton()->environment_set_tonemap(environment,VS::EnvironmentToneMapper(tone_mapper),tonemap_exposure,tonemap_white,tonemap_auto_exposure,tonemap_auto_exposure_min,tonemap_auto_exposure_max,tonemap_auto_exposure_speed,tonemap_auto_exposure_grey); +} + +float Environment::get_tonemap_exposure() const{ + + return tonemap_exposure; +} + +void Environment::set_tonemap_white(float p_white){ + + tonemap_white=p_white; + VS::get_singleton()->environment_set_tonemap(environment,VS::EnvironmentToneMapper(tone_mapper),tonemap_exposure,tonemap_white,tonemap_auto_exposure,tonemap_auto_exposure_min,tonemap_auto_exposure_max,tonemap_auto_exposure_speed,tonemap_auto_exposure_grey); + +} +float Environment::get_tonemap_white() const { + + return tonemap_white; +} + +void Environment::set_tonemap_auto_exposure(bool p_enabled) { + + tonemap_auto_exposure=p_enabled; + VS::get_singleton()->environment_set_tonemap(environment,VS::EnvironmentToneMapper(tone_mapper),tonemap_exposure,tonemap_white,tonemap_auto_exposure,tonemap_auto_exposure_min,tonemap_auto_exposure_max,tonemap_auto_exposure_speed,tonemap_auto_exposure_grey); + +} +bool Environment::get_tonemap_auto_exposure() const { + + return tonemap_auto_exposure; +} + +void Environment::set_tonemap_auto_exposure_max(float p_auto_exposure_max) { + + tonemap_auto_exposure_max=p_auto_exposure_max; + VS::get_singleton()->environment_set_tonemap(environment,VS::EnvironmentToneMapper(tone_mapper),tonemap_exposure,tonemap_white,tonemap_auto_exposure,tonemap_auto_exposure_min,tonemap_auto_exposure_max,tonemap_auto_exposure_speed,tonemap_auto_exposure_grey); + +} +float Environment::get_tonemap_auto_exposure_max() const { + + return tonemap_auto_exposure_max; +} + +void Environment::set_tonemap_auto_exposure_min(float p_auto_exposure_min) { + + tonemap_auto_exposure_min=p_auto_exposure_min; + VS::get_singleton()->environment_set_tonemap(environment,VS::EnvironmentToneMapper(tone_mapper),tonemap_exposure,tonemap_white,tonemap_auto_exposure,tonemap_auto_exposure_min,tonemap_auto_exposure_max,tonemap_auto_exposure_speed,tonemap_auto_exposure_grey); + +} +float Environment::get_tonemap_auto_exposure_min() const { + + return tonemap_auto_exposure_min; +} + +void Environment::set_tonemap_auto_exposure_speed(float p_auto_exposure_speed) { + + tonemap_auto_exposure_speed=p_auto_exposure_speed; + VS::get_singleton()->environment_set_tonemap(environment,VS::EnvironmentToneMapper(tone_mapper),tonemap_exposure,tonemap_white,tonemap_auto_exposure,tonemap_auto_exposure_min,tonemap_auto_exposure_max,tonemap_auto_exposure_speed,tonemap_auto_exposure_grey); + +} +float Environment::get_tonemap_auto_exposure_speed() const { + + return tonemap_auto_exposure_speed; +} + +void Environment::set_tonemap_auto_exposure_grey(float p_auto_exposure_grey) { + + tonemap_auto_exposure_grey=p_auto_exposure_grey; + VS::get_singleton()->environment_set_tonemap(environment,VS::EnvironmentToneMapper(tone_mapper),tonemap_exposure,tonemap_white,tonemap_auto_exposure,tonemap_auto_exposure_min,tonemap_auto_exposure_max,tonemap_auto_exposure_speed,tonemap_auto_exposure_grey); + +} +float Environment::get_tonemap_auto_exposure_grey() const { + + return tonemap_auto_exposure_grey; +} + +void Environment::set_adjustment_enable(bool p_enable) { + + adjustment_enabled=p_enable; + VS::get_singleton()->environment_set_adjustment(environment,adjustment_enabled,adjustment_brightness,adjustment_contrast,adjustment_saturation,adjustment_color_correction.is_valid()?adjustment_color_correction->get_rid():RID()); +} + +bool Environment::is_adjustment_enabled() const { + + return adjustment_enabled; +} + + +void Environment::set_adjustment_brightness(float p_brightness) { + + adjustment_brightness=p_brightness; + VS::get_singleton()->environment_set_adjustment(environment,adjustment_enabled,adjustment_brightness,adjustment_contrast,adjustment_saturation,adjustment_color_correction.is_valid()?adjustment_color_correction->get_rid():RID()); + +} +float Environment::get_adjustment_brightness() const { + + return adjustment_brightness; +} + +void Environment::set_adjustment_contrast(float p_contrast) { + + adjustment_contrast=p_contrast; + VS::get_singleton()->environment_set_adjustment(environment,adjustment_enabled,adjustment_brightness,adjustment_contrast,adjustment_saturation,adjustment_color_correction.is_valid()?adjustment_color_correction->get_rid():RID()); + +} +float Environment::get_adjustment_contrast() const { + + return adjustment_contrast; +} + +void Environment::set_adjustment_saturation(float p_saturation) { + + adjustment_saturation=p_saturation; + VS::get_singleton()->environment_set_adjustment(environment,adjustment_enabled,adjustment_brightness,adjustment_contrast,adjustment_saturation,adjustment_color_correction.is_valid()?adjustment_color_correction->get_rid():RID()); + +} +float Environment::get_adjustment_saturation() const { + + return adjustment_saturation; +} + +void Environment::set_adjustment_color_correction(const Ref<Texture>& p_ramp) { + + adjustment_color_correction=p_ramp; + VS::get_singleton()->environment_set_adjustment(environment,adjustment_enabled,adjustment_brightness,adjustment_contrast,adjustment_saturation,adjustment_color_correction.is_valid()?adjustment_color_correction->get_rid():RID()); - return environment; } +Ref<Texture> Environment::get_adjustment_color_correction() const { + + return adjustment_color_correction; +} + + +void Environment::_validate_property(PropertyInfo& property) const { + + if (property.name=="background/skybox" || property.name=="background/skybox_scale" || property.name=="ambient_light/skybox_contribution") { + if (bg_mode!=BG_SKYBOX) { + property.usage=PROPERTY_USAGE_NOEDITOR; + } + } + + if (property.name=="background/color") { + if (bg_mode!=BG_COLOR) { + property.usage=PROPERTY_USAGE_NOEDITOR; + } + } + + if (property.name=="background/canvas_max_layer") { + if (bg_mode!=BG_CANVAS) { + property.usage=PROPERTY_USAGE_NOEDITOR; + } + } + +} + +void Environment::set_ssr_enabled(bool p_enable) { + + ssr_enabled=p_enable; + VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness); +} + +bool Environment::is_ssr_enabled() const{ + + return ssr_enabled; +} + +void Environment::set_ssr_max_steps(int p_steps){ + + ssr_max_steps=p_steps; + VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness); + +} +int Environment::get_ssr_max_steps() const { + + return ssr_max_steps; +} + +void Environment::set_ssr_accel(float p_accel) { + + ssr_accel=p_accel; + VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness); + +} +float Environment::get_ssr_accel() const { + + return ssr_accel; +} + +void Environment::set_ssr_fade(float p_fade) { + + ssr_fade=p_fade; + VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness); + +} +float Environment::get_ssr_fade() const { + + return ssr_fade; +} + +void Environment::set_ssr_depth_tolerance(float p_depth_tolerance) { + + ssr_depth_tolerance=p_depth_tolerance; + VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness); + +} +float Environment::get_ssr_depth_tolerance() const { + + return ssr_depth_tolerance; +} + +void Environment::set_ssr_smooth(bool p_enable) { + + ssr_smooth=p_enable; + VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness); + +} +bool Environment::is_ssr_smooth() const { + + return ssr_smooth; +} + +void Environment::set_ssr_rough(bool p_enable) { + + ssr_roughness=p_enable; + VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness); + +} +bool Environment::is_ssr_rough() const { + + return ssr_roughness; +} + +void Environment::set_ssao_enabled(bool p_enable) { + + ssao_enabled=p_enable; + VS::get_singleton()->environment_set_ssao(environment,ssao_enabled,ssao_radius,ssao_intensity,ssao_radius2,ssao_intensity2,ssao_bias,ssao_direct_light_affect,ssao_color,ssao_blur); + +} + +bool Environment::is_ssao_enabled() const{ + + return ssao_enabled; +} + +void Environment::set_ssao_radius(float p_radius){ + + ssao_radius=p_radius; + VS::get_singleton()->environment_set_ssao(environment,ssao_enabled,ssao_radius,ssao_intensity,ssao_radius2,ssao_intensity2,ssao_bias,ssao_direct_light_affect,ssao_color,ssao_blur); +} +float Environment::get_ssao_radius() const{ + + return ssao_radius; +} + + +void Environment::set_ssao_intensity(float p_intensity){ + + ssao_intensity=p_intensity; + VS::get_singleton()->environment_set_ssao(environment,ssao_enabled,ssao_radius,ssao_intensity,ssao_radius2,ssao_intensity2,ssao_bias,ssao_direct_light_affect,ssao_color,ssao_blur); +} + +float Environment::get_ssao_intensity() const{ + + return ssao_intensity; +} + +void Environment::set_ssao_radius2(float p_radius){ + + ssao_radius2=p_radius; + VS::get_singleton()->environment_set_ssao(environment,ssao_enabled,ssao_radius,ssao_intensity,ssao_radius2,ssao_intensity2,ssao_bias,ssao_direct_light_affect,ssao_color,ssao_blur); +} +float Environment::get_ssao_radius2() const{ + + return ssao_radius2; +} + + +void Environment::set_ssao_intensity2(float p_intensity){ + + ssao_intensity2=p_intensity; + VS::get_singleton()->environment_set_ssao(environment,ssao_enabled,ssao_radius,ssao_intensity,ssao_radius2,ssao_intensity2,ssao_bias,ssao_direct_light_affect,ssao_color,ssao_blur); +} +float Environment::get_ssao_intensity2() const{ + + return ssao_intensity2; +} + +void Environment::set_ssao_bias(float p_bias){ + + ssao_bias=p_bias; + VS::get_singleton()->environment_set_ssao(environment,ssao_enabled,ssao_radius,ssao_intensity,ssao_radius2,ssao_intensity2,ssao_bias,ssao_direct_light_affect,ssao_color,ssao_blur); +} +float Environment::get_ssao_bias() const{ + + return ssao_bias; +} + +void Environment::set_ssao_direct_light_affect(float p_direct_light_affect){ + + ssao_direct_light_affect=p_direct_light_affect; + VS::get_singleton()->environment_set_ssao(environment,ssao_enabled,ssao_radius,ssao_intensity,ssao_radius2,ssao_intensity2,ssao_bias,ssao_direct_light_affect,ssao_color,ssao_blur); +} +float Environment::get_ssao_direct_light_affect() const{ + + return ssao_direct_light_affect; +} + + +void Environment::set_ssao_color(const Color& p_color) { + + ssao_color=p_color; + VS::get_singleton()->environment_set_ssao(environment,ssao_enabled,ssao_radius,ssao_intensity,ssao_radius2,ssao_intensity2,ssao_bias,ssao_direct_light_affect,ssao_color,ssao_blur); +} + +Color Environment::get_ssao_color() const { + + return ssao_color; +} + +void Environment::set_ssao_blur(bool p_enable) { + + ssao_blur=p_enable; + VS::get_singleton()->environment_set_ssao(environment,ssao_enabled,ssao_radius,ssao_intensity,ssao_radius2,ssao_intensity2,ssao_bias,ssao_direct_light_affect,ssao_color,ssao_blur); +} +bool Environment::is_ssao_blur_enabled() const { + + return ssao_blur; +} + +void Environment::set_glow_enabled(bool p_enabled) { + + glow_enabled=p_enabled; + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold,glow_bicubic_upscale); +} + +bool Environment::is_glow_enabled() const{ + + return glow_enabled; +} + +void Environment::set_glow_level(int p_level,bool p_enabled){ + + ERR_FAIL_INDEX(p_level,VS::MAX_GLOW_LEVELS); + + if (p_enabled) + glow_levels|=(1<<p_level); + else + glow_levels&=~(1<<p_level); + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold,glow_bicubic_upscale); + +} +bool Environment::is_glow_level_enabled(int p_level) const{ + + ERR_FAIL_INDEX_V(p_level,VS::MAX_GLOW_LEVELS,false); + + return glow_levels&(1<<p_level); +} + +void Environment::set_glow_intensity(float p_intensity){ + + glow_intensity=p_intensity; + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold,glow_bicubic_upscale); + +} +float Environment::get_glow_intensity() const{ + + return glow_intensity; +} + +void Environment::set_glow_strength(float p_strength){ + + glow_strength=p_strength; + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold,glow_bicubic_upscale); + +} +float Environment::get_glow_strength() const{ + + return glow_strength; +} + +void Environment::set_glow_bloom(float p_treshold){ + + glow_bloom=p_treshold; + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold,glow_bicubic_upscale); + +} +float Environment::get_glow_bloom() const{ + + return glow_bloom; +} + +void Environment::set_glow_blend_mode(GlowBlendMode p_mode){ + + glow_blend_mode=p_mode; + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold,glow_bicubic_upscale); + +} +Environment::GlowBlendMode Environment::get_glow_blend_mode() const{ + + return glow_blend_mode; +} + +void Environment::set_glow_hdr_bleed_treshold(float p_treshold){ + + glow_hdr_bleed_treshold=p_treshold; + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold,glow_bicubic_upscale); + +} +float Environment::get_glow_hdr_bleed_treshold() const{ + + return glow_hdr_bleed_treshold; +} + +void Environment::set_glow_hdr_bleed_scale(float p_scale){ + + glow_hdr_bleed_scale=p_scale; + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold,glow_bicubic_upscale); + +} +float Environment::get_glow_hdr_bleed_scale() const{ + + return glow_hdr_bleed_scale; +} + +void Environment::set_glow_bicubic_upscale(bool p_enable) { + + glow_bicubic_upscale=p_enable; + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold,glow_bicubic_upscale); + +} + +bool Environment::is_glow_bicubic_upscale_enabled() const { + + return glow_bicubic_upscale; +} + + +void Environment::set_dof_blur_far_enabled(bool p_enable) { + + dof_blur_far_enabled=p_enable; + VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); +} + +bool Environment::is_dof_blur_far_enabled() const{ + + return dof_blur_far_enabled; +} + +void Environment::set_dof_blur_far_distance(float p_distance){ + + dof_blur_far_distance=p_distance; + VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); + +} +float Environment::get_dof_blur_far_distance() const{ + + return dof_blur_far_distance; +} + +void Environment::set_dof_blur_far_transition(float p_distance){ + + dof_blur_far_transition=p_distance; + VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); +} +float Environment::get_dof_blur_far_transition() const{ + + return dof_blur_far_transition; +} + +void Environment::set_dof_blur_far_amount(float p_amount){ + + dof_blur_far_amount=p_amount; + VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); + +} +float Environment::get_dof_blur_far_amount() const{ + + return dof_blur_far_amount; +} + +void Environment::set_dof_blur_far_quality(DOFBlurQuality p_quality) { + + dof_blur_far_quality=p_quality; + VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); +} + +Environment::DOFBlurQuality Environment::get_dof_blur_far_quality() const { + + return dof_blur_far_quality; +} + + +void Environment::set_dof_blur_near_enabled(bool p_enable) { + + dof_blur_near_enabled=p_enable; + VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); +} + +bool Environment::is_dof_blur_near_enabled() const{ + + return dof_blur_near_enabled; +} + +void Environment::set_dof_blur_near_distance(float p_distance){ + + dof_blur_near_distance=p_distance; + VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); +} + +float Environment::get_dof_blur_near_distance() const{ + + return dof_blur_near_distance; +} + +void Environment::set_dof_blur_near_transition(float p_distance){ + + dof_blur_near_transition=p_distance; + VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); +} + +float Environment::get_dof_blur_near_transition() const{ + + return dof_blur_near_transition; +} + +void Environment::set_dof_blur_near_amount(float p_amount){ + + dof_blur_near_amount=p_amount; + VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); +} + +float Environment::get_dof_blur_near_amount() const{ + + return dof_blur_near_amount; +} + +void Environment::set_dof_blur_near_quality(DOFBlurQuality p_quality) { + + dof_blur_near_quality=p_quality; + VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); +} + +Environment::DOFBlurQuality Environment::get_dof_blur_near_quality() const { + + return dof_blur_near_quality; +} + void Environment::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_background","bgmode"),&Environment::set_background); + ObjectTypeDB::bind_method(_MD("set_background","mode"),&Environment::set_background); + ObjectTypeDB::bind_method(_MD("set_skybox","skybox:CubeMap"),&Environment::set_skybox); + ObjectTypeDB::bind_method(_MD("set_skybox_scale","scale"),&Environment::set_skybox_scale); + ObjectTypeDB::bind_method(_MD("set_bg_color","color"),&Environment::set_bg_color); + ObjectTypeDB::bind_method(_MD("set_bg_energy","energy"),&Environment::set_bg_energy); + ObjectTypeDB::bind_method(_MD("set_canvas_max_layer","layer"),&Environment::set_canvas_max_layer); + ObjectTypeDB::bind_method(_MD("set_ambient_light_color","color"),&Environment::set_ambient_light_color); + ObjectTypeDB::bind_method(_MD("set_ambient_light_energy","energy"),&Environment::set_ambient_light_energy); + ObjectTypeDB::bind_method(_MD("set_ambient_light_skybox_contribution","energy"),&Environment::set_ambient_light_skybox_contribution); + + ObjectTypeDB::bind_method(_MD("get_background"),&Environment::get_background); + ObjectTypeDB::bind_method(_MD("get_skybox:CubeMap"),&Environment::get_skybox); + ObjectTypeDB::bind_method(_MD("get_skybox_scale"),&Environment::get_skybox_scale); + ObjectTypeDB::bind_method(_MD("get_bg_color"),&Environment::get_bg_color); + ObjectTypeDB::bind_method(_MD("get_bg_energy"),&Environment::get_bg_energy); + ObjectTypeDB::bind_method(_MD("get_canvas_max_layer"),&Environment::get_canvas_max_layer); + ObjectTypeDB::bind_method(_MD("get_ambient_light_color"),&Environment::get_ambient_light_color); + ObjectTypeDB::bind_method(_MD("get_ambient_light_energy"),&Environment::get_ambient_light_energy); + ObjectTypeDB::bind_method(_MD("get_ambient_light_skybox_contribution"),&Environment::get_ambient_light_skybox_contribution); + + + ADD_PROPERTY(PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Clear Color,Custom Color,Skybox,Canvas,Keep"),_SCS("set_background"),_SCS("get_background") ); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"background/skybox",PROPERTY_HINT_RESOURCE_TYPE,"SkyBox"),_SCS("set_skybox"),_SCS("get_skybox") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"background/skybox_scale",PROPERTY_HINT_RANGE,"0,32,0.01"),_SCS("set_skybox_scale"),_SCS("get_skybox_scale") ); + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"background/color"),_SCS("set_bg_color"),_SCS("get_bg_color") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"background/energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_bg_energy"),_SCS("get_bg_energy") ); + ADD_PROPERTY(PropertyInfo(Variant::INT,"background/canvas_max_layer",PROPERTY_HINT_RANGE,"-1000,1000,1"),_SCS("set_canvas_max_layer"),_SCS("get_canvas_max_layer") ); + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"ambient_light/color"),_SCS("set_ambient_light_color"),_SCS("get_ambient_light_color") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_ambient_light_energy"),_SCS("get_ambient_light_energy") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/skybox_contribution",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_ambient_light_skybox_contribution"),_SCS("get_ambient_light_skybox_contribution") ); + + + ObjectTypeDB::bind_method(_MD("set_ssr_enabled","enabled"),&Environment::set_ssr_enabled); + ObjectTypeDB::bind_method(_MD("is_ssr_enabled"),&Environment::is_ssr_enabled); + + ObjectTypeDB::bind_method(_MD("set_ssr_max_steps","max_steps"),&Environment::set_ssr_max_steps); + ObjectTypeDB::bind_method(_MD("get_ssr_max_steps"),&Environment::get_ssr_max_steps); + + ObjectTypeDB::bind_method(_MD("set_ssr_accel","accel"),&Environment::set_ssr_accel); + ObjectTypeDB::bind_method(_MD("get_ssr_accel"),&Environment::get_ssr_accel); + + ObjectTypeDB::bind_method(_MD("set_ssr_fade","fade"),&Environment::set_ssr_fade); + ObjectTypeDB::bind_method(_MD("get_ssr_fade"),&Environment::get_ssr_fade); + + ObjectTypeDB::bind_method(_MD("set_ssr_depth_tolerance","depth_tolerance"),&Environment::set_ssr_depth_tolerance); + ObjectTypeDB::bind_method(_MD("get_ssr_depth_tolerance"),&Environment::get_ssr_depth_tolerance); + + ObjectTypeDB::bind_method(_MD("set_ssr_smooth","smooth"),&Environment::set_ssr_smooth); + ObjectTypeDB::bind_method(_MD("is_ssr_smooth"),&Environment::is_ssr_smooth); + + ObjectTypeDB::bind_method(_MD("set_ssr_rough","rough"),&Environment::set_ssr_rough); + ObjectTypeDB::bind_method(_MD("is_ssr_rough"),&Environment::is_ssr_rough); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ss_reflections/enabled"),_SCS("set_ssr_enabled"),_SCS("is_ssr_enabled") ); + ADD_PROPERTY(PropertyInfo(Variant::INT,"ss_reflections/max_steps",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_ssr_max_steps"),_SCS("get_ssr_max_steps") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ss_reflections/accel",PROPERTY_HINT_RANGE,"0,4,0.01"),_SCS("set_ssr_accel"),_SCS("get_ssr_accel") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ss_reflections/fade",PROPERTY_HINT_EXP_EASING),_SCS("set_ssr_fade"),_SCS("get_ssr_fade") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ss_reflections/depth_tolerance",PROPERTY_HINT_RANGE,"0.1,128,0.1"),_SCS("set_ssr_depth_tolerance"),_SCS("get_ssr_depth_tolerance") ); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ss_reflections/accel_smooth"),_SCS("set_ssr_smooth"),_SCS("is_ssr_smooth") ); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ss_reflections/roughness"),_SCS("set_ssr_rough"),_SCS("is_ssr_rough") ); + + ObjectTypeDB::bind_method(_MD("set_ssao_enabled","enabled"),&Environment::set_ssao_enabled); + ObjectTypeDB::bind_method(_MD("is_ssao_enabled"),&Environment::is_ssao_enabled); + + ObjectTypeDB::bind_method(_MD("set_ssao_radius","radius"),&Environment::set_ssao_radius); + ObjectTypeDB::bind_method(_MD("get_ssao_radius"),&Environment::get_ssao_radius); + + ObjectTypeDB::bind_method(_MD("set_ssao_intensity","intensity"),&Environment::set_ssao_intensity); + ObjectTypeDB::bind_method(_MD("get_ssao_intensity"),&Environment::get_ssao_intensity); + + ObjectTypeDB::bind_method(_MD("set_ssao_radius2","radius"),&Environment::set_ssao_radius2); + ObjectTypeDB::bind_method(_MD("get_ssao_radius2"),&Environment::get_ssao_radius2); + + ObjectTypeDB::bind_method(_MD("set_ssao_intensity2","intensity"),&Environment::set_ssao_intensity2); + ObjectTypeDB::bind_method(_MD("get_ssao_intensity2"),&Environment::get_ssao_intensity2); + + ObjectTypeDB::bind_method(_MD("set_ssao_bias","bias"),&Environment::set_ssao_bias); + ObjectTypeDB::bind_method(_MD("get_ssao_bias"),&Environment::get_ssao_bias); + + ObjectTypeDB::bind_method(_MD("set_ssao_direct_light_affect","amount"),&Environment::set_ssao_direct_light_affect); + ObjectTypeDB::bind_method(_MD("get_ssao_direct_light_affect"),&Environment::get_ssao_direct_light_affect); + + ObjectTypeDB::bind_method(_MD("set_ssao_color","color"),&Environment::set_ssao_color); + ObjectTypeDB::bind_method(_MD("get_ssao_color"),&Environment::get_ssao_color); + + ObjectTypeDB::bind_method(_MD("set_ssao_blur","enabled"),&Environment::set_ssao_blur); + ObjectTypeDB::bind_method(_MD("is_ssao_blur_enabled"),&Environment::is_ssao_blur_enabled); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ambient_occlusion/enabled"),_SCS("set_ssao_enabled"),_SCS("is_ssao_enabled") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_occlusion/radius",PROPERTY_HINT_RANGE,"0.1,16,0.1"),_SCS("set_ssao_radius"),_SCS("get_ssao_radius") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_occlusion/intensity",PROPERTY_HINT_RANGE,"0.0,9,0.1"),_SCS("set_ssao_intensity"),_SCS("get_ssao_intensity") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_occlusion/radius2",PROPERTY_HINT_RANGE,"0.0,16,0.1"),_SCS("set_ssao_radius2"),_SCS("get_ssao_radius2") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_occlusion/intensity2",PROPERTY_HINT_RANGE,"0.0,9,0.1"),_SCS("set_ssao_intensity2"),_SCS("get_ssao_intensity2") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_occlusion/bias",PROPERTY_HINT_RANGE,"0.001,8,0.001"),_SCS("set_ssao_bias"),_SCS("get_ssao_bias") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_occlusion/light_affect",PROPERTY_HINT_RANGE,"0.00,1,0.01"),_SCS("set_ssao_direct_light_affect"),_SCS("get_ssao_direct_light_affect") ); + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"ambient_occlusion/color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("set_ssao_color"),_SCS("get_ssao_color") ); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ambient_occlusion/blur"),_SCS("set_ssao_blur"),_SCS("is_ssao_blur_enabled") ); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_far_enabled","enabled"),&Environment::set_dof_blur_far_enabled); + ObjectTypeDB::bind_method(_MD("is_dof_blur_far_enabled"),&Environment::is_dof_blur_far_enabled); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_far_distance","intensity"),&Environment::set_dof_blur_far_distance); + ObjectTypeDB::bind_method(_MD("get_dof_blur_far_distance"),&Environment::get_dof_blur_far_distance); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_far_transition","intensity"),&Environment::set_dof_blur_far_transition); + ObjectTypeDB::bind_method(_MD("get_dof_blur_far_transition"),&Environment::get_dof_blur_far_transition); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_far_amount","intensity"),&Environment::set_dof_blur_far_amount); + ObjectTypeDB::bind_method(_MD("get_dof_blur_far_amount"),&Environment::get_dof_blur_far_amount); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_far_quality","intensity"),&Environment::set_dof_blur_far_quality); + ObjectTypeDB::bind_method(_MD("get_dof_blur_far_quality"),&Environment::get_dof_blur_far_quality); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_near_enabled","enabled"),&Environment::set_dof_blur_near_enabled); + ObjectTypeDB::bind_method(_MD("is_dof_blur_near_enabled"),&Environment::is_dof_blur_near_enabled); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_near_distance","intensity"),&Environment::set_dof_blur_near_distance); + ObjectTypeDB::bind_method(_MD("get_dof_blur_near_distance"),&Environment::get_dof_blur_near_distance); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_near_transition","intensity"),&Environment::set_dof_blur_near_transition); + ObjectTypeDB::bind_method(_MD("get_dof_blur_near_transition"),&Environment::get_dof_blur_near_transition); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_near_amount","intensity"),&Environment::set_dof_blur_near_amount); + ObjectTypeDB::bind_method(_MD("get_dof_blur_near_amount"),&Environment::get_dof_blur_near_amount); + + ObjectTypeDB::bind_method(_MD("set_dof_blur_near_quality","level"),&Environment::set_dof_blur_near_quality); + ObjectTypeDB::bind_method(_MD("get_dof_blur_near_quality"),&Environment::get_dof_blur_near_quality); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"dof_blur_far/enabled"),_SCS("set_dof_blur_far_enabled"),_SCS("is_dof_blur_far_enabled") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_far/distance",PROPERTY_HINT_EXP_RANGE,"0.01,8192,0.01"),_SCS("set_dof_blur_far_distance"),_SCS("get_dof_blur_far_distance") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_far/transition",PROPERTY_HINT_EXP_RANGE,"0.01,8192,0.01"),_SCS("set_dof_blur_far_transition"),_SCS("get_dof_blur_far_transition") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_far/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_dof_blur_far_amount"),_SCS("get_dof_blur_far_amount") ); + ADD_PROPERTY(PropertyInfo(Variant::INT,"dof_blur_far/quality",PROPERTY_HINT_ENUM,"Low,Medium,High"),_SCS("set_dof_blur_far_quality"),_SCS("get_dof_blur_far_quality") ); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"dof_blur_near/enabled"),_SCS("set_dof_blur_near_enabled"),_SCS("is_dof_blur_near_enabled") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_near/distance",PROPERTY_HINT_EXP_RANGE,"0.01,8192,0.01"),_SCS("set_dof_blur_near_distance"),_SCS("get_dof_blur_near_distance") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_near/transition",PROPERTY_HINT_EXP_RANGE,"0.01,8192,0.01"),_SCS("set_dof_blur_near_transition"),_SCS("get_dof_blur_near_transition") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_near/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_dof_blur_near_amount"),_SCS("get_dof_blur_near_amount") ); + ADD_PROPERTY(PropertyInfo(Variant::INT,"dof_blur_near/quality",PROPERTY_HINT_ENUM,"Low,Medium,High"),_SCS("set_dof_blur_near_quality"),_SCS("get_dof_blur_near_quality") ); + + + ObjectTypeDB::bind_method(_MD("set_glow_enabled","enabled"),&Environment::set_glow_enabled); + ObjectTypeDB::bind_method(_MD("is_glow_enabled"),&Environment::is_glow_enabled); + + ObjectTypeDB::bind_method(_MD("set_glow_level","idx","enabled"),&Environment::set_glow_level); + ObjectTypeDB::bind_method(_MD("is_glow_level_enabled","idx"),&Environment::is_glow_level_enabled); + + ObjectTypeDB::bind_method(_MD("set_glow_intensity","intensity"),&Environment::set_glow_intensity); + ObjectTypeDB::bind_method(_MD("get_glow_intensity"),&Environment::get_glow_intensity); + + ObjectTypeDB::bind_method(_MD("set_glow_strength","strength"),&Environment::set_glow_strength); + ObjectTypeDB::bind_method(_MD("get_glow_strength"),&Environment::get_glow_strength); + + ObjectTypeDB::bind_method(_MD("set_glow_bloom","amount"),&Environment::set_glow_bloom); + ObjectTypeDB::bind_method(_MD("get_glow_bloom"),&Environment::get_glow_bloom); + + ObjectTypeDB::bind_method(_MD("set_glow_blend_mode","mode"),&Environment::set_glow_blend_mode); + ObjectTypeDB::bind_method(_MD("get_glow_blend_mode"),&Environment::get_glow_blend_mode); + + ObjectTypeDB::bind_method(_MD("set_glow_hdr_bleed_treshold","treshold"),&Environment::set_glow_hdr_bleed_treshold); + ObjectTypeDB::bind_method(_MD("get_glow_hdr_bleed_treshold"),&Environment::get_glow_hdr_bleed_treshold); + + ObjectTypeDB::bind_method(_MD("set_glow_hdr_bleed_scale","scale"),&Environment::set_glow_hdr_bleed_scale); + ObjectTypeDB::bind_method(_MD("get_glow_hdr_bleed_scale"),&Environment::get_glow_hdr_bleed_scale); + + ObjectTypeDB::bind_method(_MD("set_glow_bicubic_upscale","enabled"),&Environment::set_glow_bicubic_upscale); + ObjectTypeDB::bind_method(_MD("is_glow_bicubic_upscale_enabled"),&Environment::is_glow_bicubic_upscale_enabled); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"glow/enabled"),_SCS("set_glow_enabled"),_SCS("is_glow_enabled") ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/1"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),0 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/2"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),1 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/3"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),2 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/4"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),3 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/5"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),4 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/6"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),5 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/7"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),6 ); + + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/intensity",PROPERTY_HINT_RANGE,"0.0,8.0,0.01"),_SCS("set_glow_intensity"),_SCS("get_glow_intensity") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/strength",PROPERTY_HINT_RANGE,"0.0,2.0,0.01"),_SCS("set_glow_strength"),_SCS("get_glow_strength") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/bloom",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_glow_bloom"),_SCS("get_glow_bloom") ); + ADD_PROPERTY(PropertyInfo(Variant::INT,"glow/blend_mode",PROPERTY_HINT_ENUM,"Additive,Screen,Softlight,Replace"),_SCS("set_glow_blend_mode"),_SCS("get_glow_blend_mode") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/hdr_treshold",PROPERTY_HINT_RANGE,"0.0,4.0,0.01"),_SCS("set_glow_hdr_bleed_treshold"),_SCS("get_glow_hdr_bleed_treshold") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/hdr_scale",PROPERTY_HINT_RANGE,"0.0,4.0,0.01"),_SCS("set_glow_hdr_bleed_scale"),_SCS("get_glow_hdr_bleed_scale") ); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"glow/bicubic_upscale"),_SCS("set_glow_bicubic_upscale"),_SCS("is_glow_bicubic_upscale_enabled") ); + + + ObjectTypeDB::bind_method(_MD("set_tonemapper","mode"),&Environment::set_tonemapper); + ObjectTypeDB::bind_method(_MD("get_tonemapper"),&Environment::get_tonemapper); + + ObjectTypeDB::bind_method(_MD("set_tonemap_exposure","exposure"),&Environment::set_tonemap_exposure); + ObjectTypeDB::bind_method(_MD("get_tonemap_exposure"),&Environment::get_tonemap_exposure); + + ObjectTypeDB::bind_method(_MD("set_tonemap_white","white"),&Environment::set_tonemap_white); + ObjectTypeDB::bind_method(_MD("get_tonemap_white"),&Environment::get_tonemap_white); + + ObjectTypeDB::bind_method(_MD("set_tonemap_auto_exposure","auto_exposure"),&Environment::set_tonemap_auto_exposure); + ObjectTypeDB::bind_method(_MD("get_tonemap_auto_exposure"),&Environment::get_tonemap_auto_exposure); + + ObjectTypeDB::bind_method(_MD("set_tonemap_auto_exposure_max","exposure_max"),&Environment::set_tonemap_auto_exposure_max); + ObjectTypeDB::bind_method(_MD("get_tonemap_auto_exposure_max"),&Environment::get_tonemap_auto_exposure_max); + + ObjectTypeDB::bind_method(_MD("set_tonemap_auto_exposure_min","exposure_min"),&Environment::set_tonemap_auto_exposure_min); + ObjectTypeDB::bind_method(_MD("get_tonemap_auto_exposure_min"),&Environment::get_tonemap_auto_exposure_min); + + ObjectTypeDB::bind_method(_MD("set_tonemap_auto_exposure_speed","exposure_speed"),&Environment::set_tonemap_auto_exposure_speed); + ObjectTypeDB::bind_method(_MD("get_tonemap_auto_exposure_speed"),&Environment::get_tonemap_auto_exposure_speed); + + ObjectTypeDB::bind_method(_MD("set_tonemap_auto_exposure_grey","exposure_grey"),&Environment::set_tonemap_auto_exposure_grey); + ObjectTypeDB::bind_method(_MD("get_tonemap_auto_exposure_grey"),&Environment::get_tonemap_auto_exposure_grey); + + + ADD_PROPERTY(PropertyInfo(Variant::INT,"tonemap/mode",PROPERTY_HINT_ENUM,"Linear,Reindhart,Filmic,Aces"),_SCS("set_tonemapper"),_SCS("get_tonemapper") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"tonemap/exposure",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_exposure"),_SCS("get_tonemap_exposure") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"tonemap/white",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_white"),_SCS("get_tonemap_white") ); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"auto_exposure/enabled"),_SCS("set_tonemap_auto_exposure"),_SCS("get_tonemap_auto_exposure") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"auto_exposure/scale",PROPERTY_HINT_RANGE,"0.01,64,0.01"),_SCS("set_tonemap_auto_exposure_grey"),_SCS("get_tonemap_auto_exposure_grey") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"auto_exposure/min_luma",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_auto_exposure_min"),_SCS("get_tonemap_auto_exposure_min") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"auto_exposure/max_luma",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_auto_exposure_max"),_SCS("get_tonemap_auto_exposure_max") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"auto_exposure/speed",PROPERTY_HINT_RANGE,"0.01,64,0.01"),_SCS("set_tonemap_auto_exposure_speed"),_SCS("get_tonemap_auto_exposure_speed") ); + + ObjectTypeDB::bind_method(_MD("set_adjustment_enable","enabled"),&Environment::set_adjustment_enable); + ObjectTypeDB::bind_method(_MD("is_adjustment_enabled"),&Environment::is_adjustment_enabled); + + ObjectTypeDB::bind_method(_MD("set_adjustment_brightness","brightness"),&Environment::set_adjustment_brightness); + ObjectTypeDB::bind_method(_MD("get_adjustment_brightness"),&Environment::get_adjustment_brightness); + + ObjectTypeDB::bind_method(_MD("set_adjustment_contrast","contrast"),&Environment::set_adjustment_contrast); + ObjectTypeDB::bind_method(_MD("get_adjustment_contrast"),&Environment::get_adjustment_contrast); + + ObjectTypeDB::bind_method(_MD("set_adjustment_saturation","saturation"),&Environment::set_adjustment_saturation); + ObjectTypeDB::bind_method(_MD("get_adjustment_saturation"),&Environment::get_adjustment_saturation); + + ObjectTypeDB::bind_method(_MD("set_adjustment_color_correction","color_correction"),&Environment::set_adjustment_color_correction); + ObjectTypeDB::bind_method(_MD("get_adjustment_color_correction"),&Environment::get_adjustment_color_correction); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"adjustment/enabled"),_SCS("set_adjustment_enable"),_SCS("is_adjustment_enabled") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"adjustment/brightness",PROPERTY_HINT_RANGE,"0.01,8,0.01"),_SCS("set_adjustment_brightness"),_SCS("get_adjustment_brightness") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"adjustment/contrast",PROPERTY_HINT_RANGE,"0.01,8,0.01"),_SCS("set_adjustment_contrast"),_SCS("get_adjustment_contrast") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"adjustment/saturation",PROPERTY_HINT_RANGE,"0.01,8,0.01"),_SCS("set_adjustment_saturation"),_SCS("get_adjustment_saturation") ); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"adjustment/color_correction",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_adjustment_color_correction"),_SCS("get_adjustment_color_correction") ); + + + GLOBAL_DEF("rendering/skybox/irradiance_cube_resolution",256); + GLOBAL_DEF("rendering/skybox/radiance_cube_resolution",64); + + BIND_CONSTANT(BG_KEEP); + BIND_CONSTANT(BG_CLEAR_COLOR); + BIND_CONSTANT(BG_COLOR); + BIND_CONSTANT(BG_SKYBOX); + BIND_CONSTANT(BG_CANVAS); + BIND_CONSTANT(BG_MAX); + BIND_CONSTANT(GLOW_BLEND_MODE_ADDITIVE); + BIND_CONSTANT(GLOW_BLEND_MODE_SCREEN); + BIND_CONSTANT(GLOW_BLEND_MODE_SOFTLIGHT); + BIND_CONSTANT(GLOW_BLEND_MODE_REPLACE); + BIND_CONSTANT(TONE_MAPPER_LINEAR); + BIND_CONSTANT(TONE_MAPPER_REINHARDT); + BIND_CONSTANT(TONE_MAPPER_FILMIC); + BIND_CONSTANT(TONE_MAPPER_ACES); + BIND_CONSTANT(DOF_BLUR_QUALITY_LOW); + BIND_CONSTANT(DOF_BLUR_QUALITY_MEDIUM); + BIND_CONSTANT(DOF_BLUR_QUALITY_HIGH); - ObjectTypeDB::bind_method(_MD("set_background_param","param","value"),&Environment::set_background_param); - ObjectTypeDB::bind_method(_MD("get_background_param","param"),&Environment::get_background_param); - - ObjectTypeDB::bind_method(_MD("set_enable_fx","effect","enabled"),&Environment::set_enable_fx); - ObjectTypeDB::bind_method(_MD("is_fx_enabled","effect"),&Environment::is_fx_enabled); - - ObjectTypeDB::bind_method(_MD("fx_set_param","param","value"),&Environment::fx_set_param); - ObjectTypeDB::bind_method(_MD("fx_get_param","param"),&Environment::fx_get_param); - - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"ambient_light/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_AMBIENT_LIGHT); - ADD_PROPERTYI( PropertyInfo(Variant::COLOR,"ambient_light/color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_AMBIENT_LIGHT_COLOR); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"ambient_light/energy",PROPERTY_HINT_RANGE,"0,64,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_AMBIENT_LIGHT_ENERGY); - - - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"fxaa/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_FXAA); - - ADD_PROPERTY( PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Keep,Default Color,Color,Texture,Cubemap,Canvas"),_SCS("set_background"),_SCS("get_background")); - ADD_PROPERTYI( PropertyInfo(Variant::COLOR,"background/color"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_COLOR); - ADD_PROPERTYI( PropertyInfo(Variant::OBJECT,"background/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_TEXTURE); - ADD_PROPERTYI( PropertyInfo(Variant::OBJECT,"background/cubemap",PROPERTY_HINT_RESOURCE_TYPE,"CubeMap"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_CUBEMAP); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/energy",PROPERTY_HINT_RANGE,"0,128,0.01"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_ENERGY); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/scale",PROPERTY_HINT_RANGE,"0.001,16,0.001"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_SCALE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/glow",PROPERTY_HINT_RANGE,"0.00,8,0.01"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_GLOW); - ADD_PROPERTYI( PropertyInfo(Variant::INT,"background/canvas_max_layer"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_CANVAS_MAX_LAYER); - - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"glow/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_GLOW); - ADD_PROPERTYI( PropertyInfo(Variant::INT,"glow/blur_passes",PROPERTY_HINT_RANGE,"1,4,1"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_PASSES); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/blur_scale",PROPERTY_HINT_RANGE,"0.01,4,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_SCALE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/blur_strength",PROPERTY_HINT_RANGE,"0.01,4,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_STRENGTH); - ADD_PROPERTYI( PropertyInfo(Variant::INT,"glow/blur_blend_mode",PROPERTY_HINT_ENUM,"Additive,Screen,SoftLight"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_BLEND_MODE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/bloom",PROPERTY_HINT_RANGE,"0,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLOOM); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/bloom_treshold",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLOOM_TRESHOLD); - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"dof_blur/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_DOF_BLUR); - ADD_PROPERTYI( PropertyInfo(Variant::INT,"dof_blur/blur_passes",PROPERTY_HINT_RANGE,"1,4,1"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_DOF_BLUR_PASSES); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"dof_blur/begin",PROPERTY_HINT_RANGE,"0,4096,0.1"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_DOF_BLUR_BEGIN); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"dof_blur/range",PROPERTY_HINT_RANGE,"0,4096,0.1"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_DOF_BLUR_RANGE); - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"hdr/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_HDR); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/tonemapper",PROPERTY_HINT_ENUM,"Linear,Log,Reinhardt,ReinhardtAutoWhite"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_TONEMAPPER); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/exposure",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_EXPOSURE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/white",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_WHITE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/glow_treshold",PROPERTY_HINT_RANGE,"0.00,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_GLOW_TRESHOLD); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/glow_scale",PROPERTY_HINT_RANGE,"0.00,16,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_GLOW_SCALE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/min_luminance",PROPERTY_HINT_RANGE,"0.01,64,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_MIN_LUMINANCE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/max_luminance",PROPERTY_HINT_RANGE,"0.01,64,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_MAX_LUMINANCE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/exposure_adj_speed",PROPERTY_HINT_RANGE,"0.001,64,0.001"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_EXPOSURE_ADJUST_SPEED); - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"fog/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_FOG); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"fog/begin",PROPERTY_HINT_RANGE,"0.01,4096,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_FOG_BEGIN); - ADD_PROPERTYI( PropertyInfo(Variant::COLOR,"fog/begin_color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_FOG_BEGIN_COLOR); - ADD_PROPERTYI( PropertyInfo(Variant::COLOR,"fog/end_color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_FOG_END_COLOR); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"fog/attenuation",PROPERTY_HINT_EXP_EASING),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_FOG_ATTENUATION); - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"fog/bg"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_FOG_BG); - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"bcs/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_BCS); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"bcs/brightness",PROPERTY_HINT_RANGE,"0.01,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_BCS_BRIGHTNESS); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"bcs/contrast",PROPERTY_HINT_RANGE,"0.01,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_BCS_CONTRAST); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"bcs/saturation",PROPERTY_HINT_RANGE,"0.01,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_BCS_SATURATION); - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"srgb/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_SRGB); - - - - - -/* - FX_PARAM_BLOOM_GLOW_BLUR_PASSES=VS::ENV_FX_PARAM_BLOOM_GLOW_BLUR_PASSES, - FX_PARAM_BLOOM_AMOUNT=VS::ENV_FX_PARAM_BLOOM_AMOUNT, - FX_PARAM_DOF_BLUR_PASSES=VS::ENV_FX_PARAM_DOF_BLUR_PASSES, - FX_PARAM_DOF_BLUR_BEGIN=VS::ENV_FX_PARAM_DOF_BLUR_BEGIN, - FX_PARAM_DOF_BLUR_END=VS::ENV_FX_PARAM_DOF_BLUR_END, - FX_PARAM_HDR_EXPOSURE=VS::ENV_FX_PARAM_HDR_EXPOSURE, - FX_PARAM_HDR_WHITE=VS::ENV_FX_PARAM_HDR_WHITE, - FX_PARAM_HDR_GLOW_TRESHOLD=VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD, - FX_PARAM_HDR_GLOW_SCALE=VS::ENV_FX_PARAM_HDR_GLOW_SCALE, - FX_PARAM_HDR_MIN_LUMINANCE=VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE, - FX_PARAM_HDR_MAX_LUMINANCE=VS::ENV_FX_PARAM_HDR_MAX_LUMINANCE, - FX_PARAM_HDR_EXPOSURE_ADJUST_SPEED=VS::ENV_FX_PARAM_HDR_EXPOSURE_ADJUST_SPEED, - FX_PARAM_FOG_BEGIN=VS::ENV_FX_PARAM_FOG_BEGIN, - FX_PARAM_FOG_ATTENUATION=VS::ENV_FX_PARAM_FOG_ATTENUATION, - FX_PARAM_FOG_BEGIN_COLOR=VS::ENV_FX_PARAM_FOG_BEGIN_COLOR, - FX_PARAM_FOG_END_COLOR=VS::ENV_FX_PARAM_FOG_END_COLOR, - FX_PARAM_FOG_BG=VS::ENV_FX_PARAM_FOG_BG, - FX_PARAM_GAMMA_VALUE=VS::ENV_FX_PARAM_GAMMA_VALUE, - FX_PARAM_BRIGHTNESS_VALUE=VS::ENV_FX_PARAM_BRIGHTNESS_VALUE, - FX_PARAM_CONTRAST_VALUE=VS::ENV_FX_PARAM_CONTRAST_VALUE, - FX_PARAM_SATURATION_VALUE=VS::ENV_FX_PARAM_SATURATION_VALUE, - FX_PARAM_MAX=VS::ENV_FX_PARAM_MAX -*/ - - BIND_CONSTANT( BG_KEEP ); - BIND_CONSTANT( BG_DEFAULT_COLOR ); - BIND_CONSTANT( BG_COLOR ); - BIND_CONSTANT( BG_TEXTURE ); - BIND_CONSTANT( BG_CUBEMAP ); - BIND_CONSTANT( BG_CANVAS ); - BIND_CONSTANT( BG_MAX ); - - BIND_CONSTANT( BG_PARAM_CANVAS_MAX_LAYER ); - BIND_CONSTANT( BG_PARAM_COLOR ); - BIND_CONSTANT( BG_PARAM_TEXTURE ); - BIND_CONSTANT( BG_PARAM_CUBEMAP ); - BIND_CONSTANT( BG_PARAM_ENERGY ); - BIND_CONSTANT( BG_PARAM_GLOW ); - BIND_CONSTANT( BG_PARAM_MAX ); - - - BIND_CONSTANT( FX_AMBIENT_LIGHT ); - BIND_CONSTANT( FX_FXAA ); - BIND_CONSTANT( FX_GLOW ); - BIND_CONSTANT( FX_DOF_BLUR ); - BIND_CONSTANT( FX_HDR ); - BIND_CONSTANT( FX_FOG ); - BIND_CONSTANT( FX_BCS); - BIND_CONSTANT( FX_SRGB ); - BIND_CONSTANT( FX_MAX ); - - - BIND_CONSTANT( FX_BLUR_BLEND_MODE_ADDITIVE ); - BIND_CONSTANT( FX_BLUR_BLEND_MODE_SCREEN ); - BIND_CONSTANT( FX_BLUR_BLEND_MODE_SOFTLIGHT ); - - BIND_CONSTANT( FX_HDR_TONE_MAPPER_LINEAR ); - BIND_CONSTANT( FX_HDR_TONE_MAPPER_LOG ); - BIND_CONSTANT( FX_HDR_TONE_MAPPER_REINHARDT ); - BIND_CONSTANT( FX_HDR_TONE_MAPPER_REINHARDT_AUTOWHITE ); - - BIND_CONSTANT( FX_PARAM_AMBIENT_LIGHT_COLOR ); - BIND_CONSTANT( FX_PARAM_AMBIENT_LIGHT_ENERGY ); - BIND_CONSTANT( FX_PARAM_GLOW_BLUR_PASSES ); - BIND_CONSTANT( FX_PARAM_GLOW_BLUR_SCALE ); - BIND_CONSTANT( FX_PARAM_GLOW_BLUR_STRENGTH ); - BIND_CONSTANT( FX_PARAM_GLOW_BLUR_BLEND_MODE ); - BIND_CONSTANT( FX_PARAM_GLOW_BLOOM); - BIND_CONSTANT( FX_PARAM_GLOW_BLOOM_TRESHOLD); - BIND_CONSTANT( FX_PARAM_DOF_BLUR_PASSES ); - BIND_CONSTANT( FX_PARAM_DOF_BLUR_BEGIN ); - BIND_CONSTANT( FX_PARAM_DOF_BLUR_RANGE ); - BIND_CONSTANT( FX_PARAM_HDR_TONEMAPPER); - BIND_CONSTANT( FX_PARAM_HDR_EXPOSURE ); - BIND_CONSTANT( FX_PARAM_HDR_WHITE ); - BIND_CONSTANT( FX_PARAM_HDR_GLOW_TRESHOLD ); - BIND_CONSTANT( FX_PARAM_HDR_GLOW_SCALE ); - BIND_CONSTANT( FX_PARAM_HDR_MIN_LUMINANCE ); - BIND_CONSTANT( FX_PARAM_HDR_MAX_LUMINANCE ); - BIND_CONSTANT( FX_PARAM_HDR_EXPOSURE_ADJUST_SPEED ); - BIND_CONSTANT( FX_PARAM_FOG_BEGIN ); - BIND_CONSTANT( FX_PARAM_FOG_ATTENUATION ); - BIND_CONSTANT( FX_PARAM_FOG_BEGIN_COLOR ); - BIND_CONSTANT( FX_PARAM_FOG_END_COLOR ); - BIND_CONSTANT( FX_PARAM_FOG_BG ); - BIND_CONSTANT( FX_PARAM_BCS_BRIGHTNESS ); - BIND_CONSTANT( FX_PARAM_BCS_CONTRAST ); - BIND_CONSTANT( FX_PARAM_BCS_SATURATION ); - BIND_CONSTANT( FX_PARAM_MAX ); } Environment::Environment() { + bg_mode=BG_CLEAR_COLOR; + bg_skybox_scale=1.0; + bg_energy=1.0; + bg_canvas_max_layer=0; + ambient_energy=1.0; + ambient_skybox_contribution=0; + + + tone_mapper=TONE_MAPPER_LINEAR; + tonemap_exposure=1.0; + tonemap_white=1.0; + tonemap_auto_exposure=false; + tonemap_auto_exposure_max=8; + tonemap_auto_exposure_min=0.05; + tonemap_auto_exposure_speed=0.5; + tonemap_auto_exposure_grey=0.4; + + set_tonemapper(tone_mapper); //update + + adjustment_enabled=false; + adjustment_contrast=1.0; + adjustment_saturation=1.0; + adjustment_brightness=1.0; + + set_adjustment_enable(adjustment_enabled); //update + environment = VS::get_singleton()->environment_create(); - set_background(BG_DEFAULT_COLOR); - set_background_param(BG_PARAM_COLOR,Color(0,0,0)); - set_background_param(BG_PARAM_TEXTURE,Ref<ImageTexture>()); - set_background_param(BG_PARAM_CUBEMAP,Ref<CubeMap>()); - set_background_param(BG_PARAM_ENERGY,1.0); - set_background_param(BG_PARAM_SCALE,1.0); - set_background_param(BG_PARAM_GLOW,0.0); - - for(int i=0;i<FX_MAX;i++) - set_enable_fx(Fx(i),false); - - fx_set_param(FX_PARAM_AMBIENT_LIGHT_COLOR,Color(0,0,0)); - fx_set_param(FX_PARAM_AMBIENT_LIGHT_ENERGY,1.0); - fx_set_param(FX_PARAM_GLOW_BLUR_PASSES,1); - fx_set_param(FX_PARAM_GLOW_BLUR_SCALE,1); - fx_set_param(FX_PARAM_GLOW_BLUR_STRENGTH,1); - fx_set_param(FX_PARAM_GLOW_BLOOM,0.0); - fx_set_param(FX_PARAM_GLOW_BLOOM_TRESHOLD,0.5); - fx_set_param(FX_PARAM_DOF_BLUR_PASSES,1); - fx_set_param(FX_PARAM_DOF_BLUR_BEGIN,100.0); - fx_set_param(FX_PARAM_DOF_BLUR_RANGE,10.0); - fx_set_param(FX_PARAM_HDR_TONEMAPPER,FX_HDR_TONE_MAPPER_LINEAR); - fx_set_param(FX_PARAM_HDR_EXPOSURE,0.4); - fx_set_param(FX_PARAM_HDR_WHITE,1.0); - fx_set_param(FX_PARAM_HDR_GLOW_TRESHOLD,0.95); - fx_set_param(FX_PARAM_HDR_GLOW_SCALE,0.2); - fx_set_param(FX_PARAM_HDR_MIN_LUMINANCE,0.4); - fx_set_param(FX_PARAM_HDR_MAX_LUMINANCE,8.0); - fx_set_param(FX_PARAM_HDR_EXPOSURE_ADJUST_SPEED,0.5); - fx_set_param(FX_PARAM_FOG_BEGIN,100.0); - fx_set_param(FX_PARAM_FOG_ATTENUATION,1.0); - fx_set_param(FX_PARAM_FOG_BEGIN_COLOR,Color(0,0,0)); - fx_set_param(FX_PARAM_FOG_END_COLOR,Color(0,0,0)); - fx_set_param(FX_PARAM_FOG_BG,true); - fx_set_param(FX_PARAM_BCS_BRIGHTNESS,1.0); - fx_set_param(FX_PARAM_BCS_CONTRAST,1.0); - fx_set_param(FX_PARAM_BCS_SATURATION,1.0); + ssr_enabled=false; + ssr_max_steps=64; + ssr_accel=0.04; + ssr_fade=2.0; + ssr_depth_tolerance=0.2; + ssr_smooth=true; + ssr_roughness=true; + + ssao_enabled=false; + ssao_radius=1; + ssao_intensity=1; + ssao_radius2=0; + ssao_intensity2=1; + ssao_bias=0.01; + ssao_direct_light_affect=false; + ssao_blur=true; + + glow_enabled=false; + glow_levels=(1<<2)|(1<<4); + glow_intensity=0.8; + glow_strength=1.0; + glow_bloom=0.0; + glow_blend_mode=GLOW_BLEND_MODE_SOFTLIGHT; + glow_hdr_bleed_treshold=1.0; + glow_hdr_bleed_scale=2.0; + glow_bicubic_upscale=false; + + dof_blur_far_enabled=false; + dof_blur_far_distance=10; + dof_blur_far_transition=5; + dof_blur_far_amount=0.1; + dof_blur_far_quality=DOF_BLUR_QUALITY_MEDIUM; + + dof_blur_near_enabled=false; + dof_blur_near_distance=2; + dof_blur_near_transition=1; + dof_blur_near_amount=0.1; + dof_blur_near_quality=DOF_BLUR_QUALITY_MEDIUM; } + Environment::~Environment() { VS::get_singleton()->free(environment); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index c00fa0ab51..8f2e4532a4 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -31,113 +31,288 @@ #include "resource.h" #include "servers/visual_server.h" +#include "scene/resources/texture.h" +#include "scene/resources/sky_box.h" class Environment : public Resource { OBJ_TYPE(Environment,Resource); public: - enum BG { + enum BGMode { - BG_KEEP=VS::ENV_BG_KEEP, - BG_DEFAULT_COLOR=VS::ENV_BG_DEFAULT_COLOR, - BG_COLOR=VS::ENV_BG_COLOR, - BG_TEXTURE=VS::ENV_BG_TEXTURE, - BG_CUBEMAP=VS::ENV_BG_CUBEMAP, - BG_CANVAS=VS::ENV_BG_CANVAS, - BG_MAX=VS::ENV_BG_MAX + BG_CLEAR_COLOR, + BG_COLOR, + BG_SKYBOX, + BG_CANVAS, + BG_KEEP, + BG_MAX }; - enum BGParam { - BG_PARAM_CANVAS_MAX_LAYER=VS::ENV_BG_PARAM_CANVAS_MAX_LAYER, - BG_PARAM_COLOR=VS::ENV_BG_PARAM_COLOR, - BG_PARAM_TEXTURE=VS::ENV_BG_PARAM_TEXTURE, - BG_PARAM_CUBEMAP=VS::ENV_BG_PARAM_CUBEMAP, - BG_PARAM_ENERGY=VS::ENV_BG_PARAM_ENERGY, - BG_PARAM_SCALE=VS::ENV_BG_PARAM_SCALE, - BG_PARAM_GLOW=VS::ENV_BG_PARAM_GLOW, - BG_PARAM_MAX=VS::ENV_BG_PARAM_MAX - }; - enum Fx { - FX_AMBIENT_LIGHT=VS::ENV_FX_AMBIENT_LIGHT, - FX_FXAA=VS::ENV_FX_FXAA, - FX_GLOW=VS::ENV_FX_GLOW, - FX_DOF_BLUR=VS::ENV_FX_DOF_BLUR, - FX_HDR=VS::ENV_FX_HDR, - FX_FOG=VS::ENV_FX_FOG, - FX_BCS=VS::ENV_FX_BCS, - FX_SRGB=VS::ENV_FX_SRGB, - FX_MAX=VS::ENV_FX_MAX, + enum ToneMapper { + TONE_MAPPER_LINEAR, + TONE_MAPPER_REINHARDT, + TONE_MAPPER_FILMIC, + TONE_MAPPER_ACES }; - enum FxBlurBlendMode { - FX_BLUR_BLEND_MODE_ADDITIVE, - FX_BLUR_BLEND_MODE_SCREEN, - FX_BLUR_BLEND_MODE_SOFTLIGHT, + enum GlowBlendMode { + GLOW_BLEND_MODE_ADDITIVE, + GLOW_BLEND_MODE_SCREEN, + GLOW_BLEND_MODE_SOFTLIGHT, + GLOW_BLEND_MODE_REPLACE, }; - enum FxHDRToneMapper { - FX_HDR_TONE_MAPPER_LINEAR, - FX_HDR_TONE_MAPPER_LOG, - FX_HDR_TONE_MAPPER_REINHARDT, - FX_HDR_TONE_MAPPER_REINHARDT_AUTOWHITE, + enum DOFBlurQuality { + DOF_BLUR_QUALITY_LOW, + DOF_BLUR_QUALITY_MEDIUM, + DOF_BLUR_QUALITY_HIGH, }; - enum FxParam { - FX_PARAM_AMBIENT_LIGHT_COLOR=VS::ENV_FX_PARAM_AMBIENT_LIGHT_COLOR, - FX_PARAM_AMBIENT_LIGHT_ENERGY=VS::ENV_FX_PARAM_AMBIENT_LIGHT_ENERGY, - FX_PARAM_GLOW_BLUR_PASSES=VS::ENV_FX_PARAM_GLOW_BLUR_PASSES, - FX_PARAM_GLOW_BLUR_SCALE=VS::ENV_FX_PARAM_GLOW_BLUR_SCALE, - FX_PARAM_GLOW_BLUR_STRENGTH=VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH, - FX_PARAM_GLOW_BLUR_BLEND_MODE=VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE, - FX_PARAM_GLOW_BLOOM=VS::ENV_FX_PARAM_GLOW_BLOOM, - FX_PARAM_GLOW_BLOOM_TRESHOLD=VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD, - FX_PARAM_DOF_BLUR_PASSES=VS::ENV_FX_PARAM_DOF_BLUR_PASSES, - FX_PARAM_DOF_BLUR_BEGIN=VS::ENV_FX_PARAM_DOF_BLUR_BEGIN, - FX_PARAM_DOF_BLUR_RANGE=VS::ENV_FX_PARAM_DOF_BLUR_RANGE, - FX_PARAM_HDR_EXPOSURE=VS::ENV_FX_PARAM_HDR_EXPOSURE, - FX_PARAM_HDR_TONEMAPPER=VS::ENV_FX_PARAM_HDR_TONEMAPPER, - FX_PARAM_HDR_WHITE=VS::ENV_FX_PARAM_HDR_WHITE, - FX_PARAM_HDR_GLOW_TRESHOLD=VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD, - FX_PARAM_HDR_GLOW_SCALE=VS::ENV_FX_PARAM_HDR_GLOW_SCALE, - FX_PARAM_HDR_MIN_LUMINANCE=VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE, - FX_PARAM_HDR_MAX_LUMINANCE=VS::ENV_FX_PARAM_HDR_MAX_LUMINANCE, - FX_PARAM_HDR_EXPOSURE_ADJUST_SPEED=VS::ENV_FX_PARAM_HDR_EXPOSURE_ADJUST_SPEED, - FX_PARAM_FOG_BEGIN=VS::ENV_FX_PARAM_FOG_BEGIN, - FX_PARAM_FOG_BEGIN_COLOR=VS::ENV_FX_PARAM_FOG_BEGIN_COLOR, - FX_PARAM_FOG_END_COLOR=VS::ENV_FX_PARAM_FOG_END_COLOR, - FX_PARAM_FOG_ATTENUATION=VS::ENV_FX_PARAM_FOG_ATTENUATION, - FX_PARAM_FOG_BG=VS::ENV_FX_PARAM_FOG_BG, - FX_PARAM_BCS_BRIGHTNESS=VS::ENV_FX_PARAM_BCS_BRIGHTNESS, - FX_PARAM_BCS_CONTRAST=VS::ENV_FX_PARAM_BCS_CONTRAST, - FX_PARAM_BCS_SATURATION=VS::ENV_FX_PARAM_BCS_SATURATION, - FX_PARAM_MAX=VS::ENV_FX_PARAM_MAX - }; private: - - BG bg_mode; - Variant bg_param[BG_PARAM_MAX]; - bool fx_enabled[FX_MAX]; - Variant fx_param[FX_PARAM_MAX]; RID environment; + BGMode bg_mode; + Ref<SkyBox> bg_skybox; + float bg_skybox_scale; + Color bg_color; + float bg_energy; + int bg_canvas_max_layer; + Color ambient_color; + float ambient_energy; + float ambient_skybox_contribution; + + ToneMapper tone_mapper; + float tonemap_exposure; + float tonemap_white; + bool tonemap_auto_exposure; + float tonemap_auto_exposure_max; + float tonemap_auto_exposure_min; + float tonemap_auto_exposure_speed; + float tonemap_auto_exposure_grey; + + bool adjustment_enabled; + float adjustment_contrast; + float adjustment_saturation; + float adjustment_brightness; + Ref<Texture> adjustment_color_correction; + + bool ssr_enabled; + int ssr_max_steps; + float ssr_accel; + float ssr_fade; + float ssr_depth_tolerance; + bool ssr_smooth; + bool ssr_roughness; + + bool ssao_enabled; + float ssao_radius; + float ssao_intensity; + float ssao_radius2; + float ssao_intensity2; + float ssao_bias; + float ssao_direct_light_affect; + Color ssao_color; + bool ssao_blur; + + bool glow_enabled; + int glow_levels; + float glow_intensity; + float glow_strength; + float glow_bloom; + GlowBlendMode glow_blend_mode; + float glow_hdr_bleed_treshold; + float glow_hdr_bleed_scale; + bool glow_bicubic_upscale; + + bool dof_blur_far_enabled; + float dof_blur_far_distance; + float dof_blur_far_transition; + float dof_blur_far_amount; + DOFBlurQuality dof_blur_far_quality; + + bool dof_blur_near_enabled; + float dof_blur_near_distance; + float dof_blur_near_transition; + float dof_blur_near_amount; + DOFBlurQuality dof_blur_near_quality; + protected: static void _bind_methods(); + virtual void _validate_property(PropertyInfo& property) const; + public: - void set_background(BG p_bg); - BG get_background() const; - void set_background_param(BGParam p_param, const Variant& p_value); - Variant get_background_param(BGParam p_param) const; - void set_enable_fx(Fx p_effect,bool p_enabled); - bool is_fx_enabled(Fx p_effect) const; + void set_background(BGMode p_bg); + void set_skybox(const Ref<SkyBox>& p_skybox); + void set_skybox_scale(float p_scale); + void set_bg_color(const Color& p_color); + void set_bg_energy(float p_energy); + void set_canvas_max_layer(int p_max_layer); + void set_ambient_light_color(const Color& p_color); + void set_ambient_light_energy(float p_energy); + void set_ambient_light_skybox_contribution(float p_energy); + + BGMode get_background() const; + Ref<SkyBox> get_skybox() const; + float get_skybox_scale() const; + Color get_bg_color() const; + float get_bg_energy() const; + int get_canvas_max_layer() const; + Color get_ambient_light_color() const; + float get_ambient_light_energy() const; + float get_ambient_light_skybox_contribution() const; + + + void set_tonemapper(ToneMapper p_tone_mapper); + ToneMapper get_tonemapper() const; + + void set_tonemap_exposure(float p_exposure); + float get_tonemap_exposure() const; + + void set_tonemap_white(float p_white); + float get_tonemap_white() const; + + void set_tonemap_auto_exposure(bool p_enabled); + bool get_tonemap_auto_exposure() const; + + void set_tonemap_auto_exposure_max(float p_auto_exposure_max); + float get_tonemap_auto_exposure_max() const; + + void set_tonemap_auto_exposure_min(float p_auto_exposure_min); + float get_tonemap_auto_exposure_min() const; + + void set_tonemap_auto_exposure_speed(float p_auto_exposure_speed); + float get_tonemap_auto_exposure_speed() const; + + void set_tonemap_auto_exposure_grey(float p_auto_exposure_grey); + float get_tonemap_auto_exposure_grey() const; + + void set_adjustment_enable(bool p_enable); + bool is_adjustment_enabled() const; + + void set_adjustment_brightness(float p_brightness); + float get_adjustment_brightness() const; + + void set_adjustment_contrast(float p_contrast); + float get_adjustment_contrast() const; + + void set_adjustment_saturation(float p_saturation); + float get_adjustment_saturation() const; + + void set_adjustment_color_correction(const Ref<Texture>& p_ramp); + Ref<Texture> get_adjustment_color_correction() const; + + void set_ssr_enabled(bool p_enable); + bool is_ssr_enabled() const; + + void set_ssr_max_steps(int p_steps); + int get_ssr_max_steps() const; + + void set_ssr_accel(float p_accel); + float get_ssr_accel() const; + + void set_ssr_fade(float p_transition); + float get_ssr_fade() const; + + void set_ssr_depth_tolerance(float p_depth_tolerance); + float get_ssr_depth_tolerance() const; + + void set_ssr_smooth(bool p_enable); + bool is_ssr_smooth() const; + + void set_ssr_rough(bool p_enable); + bool is_ssr_rough() const; + + void set_ssao_enabled(bool p_enable); + bool is_ssao_enabled() const; + + void set_ssao_radius(float p_radius); + float get_ssao_radius() const; + + void set_ssao_intensity(float p_intensity); + float get_ssao_intensity() const; + + void set_ssao_radius2(float p_radius); + float get_ssao_radius2() const; + + void set_ssao_intensity2(float p_intensity); + float get_ssao_intensity2() const; + + void set_ssao_bias(float p_bias); + float get_ssao_bias() const; + + void set_ssao_direct_light_affect(float p_direct_light_affect); + float get_ssao_direct_light_affect() const; + + void set_ssao_color(const Color& p_color); + Color get_ssao_color() const; + + void set_ssao_blur(bool p_enable); + bool is_ssao_blur_enabled() const; + + + void set_glow_enabled(bool p_enabled); + bool is_glow_enabled() const; + + void set_glow_level(int p_level,bool p_enabled); + bool is_glow_level_enabled(int p_level) const; + + void set_glow_intensity(float p_intensity); + float get_glow_intensity() const; + + void set_glow_strength(float p_strength); + float get_glow_strength() const; + + void set_glow_bloom(float p_treshold); + float get_glow_bloom() const; + + void set_glow_blend_mode(GlowBlendMode p_mode); + GlowBlendMode get_glow_blend_mode() const; + + void set_glow_hdr_bleed_treshold(float p_treshold); + float get_glow_hdr_bleed_treshold() const; + + void set_glow_hdr_bleed_scale(float p_scale); + float get_glow_hdr_bleed_scale() const; + + void set_glow_bicubic_upscale(bool p_enable); + bool is_glow_bicubic_upscale_enabled() const; + + void set_dof_blur_far_enabled(bool p_enable); + bool is_dof_blur_far_enabled() const; + + void set_dof_blur_far_distance(float p_distance); + float get_dof_blur_far_distance() const; + + void set_dof_blur_far_transition(float p_distance); + float get_dof_blur_far_transition() const; + + void set_dof_blur_far_amount(float p_amount); + float get_dof_blur_far_amount() const; + + void set_dof_blur_far_quality(DOFBlurQuality p_quality); + DOFBlurQuality get_dof_blur_far_quality() const; + + void set_dof_blur_near_enabled(bool p_enable); + bool is_dof_blur_near_enabled() const; + + void set_dof_blur_near_distance(float p_distance); + float get_dof_blur_near_distance() const; + + void set_dof_blur_near_transition(float p_distance); + float get_dof_blur_near_transition() const; + + void set_dof_blur_near_amount(float p_amount); + float get_dof_blur_near_amount() const; + + void set_dof_blur_near_quality(DOFBlurQuality p_quality); + DOFBlurQuality get_dof_blur_near_quality() const; - void fx_set_param(FxParam p_param,const Variant& p_value); - Variant fx_get_param(FxParam p_param) const; virtual RID get_rid() const; @@ -145,9 +320,12 @@ public: ~Environment(); }; -VARIANT_ENUM_CAST( Environment::BG ); -VARIANT_ENUM_CAST( Environment::BGParam ); -VARIANT_ENUM_CAST( Environment::Fx ); -VARIANT_ENUM_CAST( Environment::FxParam ); + + + +VARIANT_ENUM_CAST(Environment::BGMode) +VARIANT_ENUM_CAST(Environment::ToneMapper) +VARIANT_ENUM_CAST(Environment::GlowBlendMode) +VARIANT_ENUM_CAST(Environment::DOFBlurQuality) #endif // ENVIRONMENT_H diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 2ecd2cc07b..a6136b2741 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -29,576 +29,1110 @@ #include "material.h" #include "scene/scene_string_names.h" +RID Material::get_rid() const { -static const char*_flag_names[Material::FLAG_MAX]={ - "visible", - "double_sided", - "invert_faces", - "unshaded", - "on_top", - "lightmap_on_uv2", - "colarray_is_srgb" -}; - + return material; +} -static const Material::Flag _flag_indices[Material::FLAG_MAX]={ - Material::FLAG_VISIBLE, - Material::FLAG_DOUBLE_SIDED, - Material::FLAG_INVERT_FACES, - Material::FLAG_UNSHADED, - Material::FLAG_ONTOP, - Material::FLAG_LIGHTMAP_ON_UV2, - Material::FLAG_COLOR_ARRAY_SRGB, -}; +Material::Material() { + material=VisualServer::get_singleton()->material_create(); +} -RID Material::get_rid() const { +Material::~Material() { - return material; + VisualServer::get_singleton()->free(material); } -void Material::set_flag(Flag p_flag,bool p_enabled) { - ERR_FAIL_INDEX(p_flag,FLAG_MAX); - flags[p_flag]=p_enabled; - VisualServer::get_singleton()->material_set_flag(material,(VS::MaterialFlag)p_flag,p_enabled); - _change_notify(); +///////////////////////////////// + +Mutex *FixedSpatialMaterial::material_mutex=NULL; +SelfList<FixedSpatialMaterial>::List FixedSpatialMaterial::dirty_materials; +Map<FixedSpatialMaterial::MaterialKey,FixedSpatialMaterial::ShaderData> FixedSpatialMaterial::shader_map; +FixedSpatialMaterial::ShaderNames* FixedSpatialMaterial::shader_names=NULL; + +void FixedSpatialMaterial::init_shaders() { + +#ifndef NO_THREADS + material_mutex = Mutex::create(); +#endif + + shader_names = memnew( ShaderNames ); + + shader_names->albedo="albedo"; + shader_names->specular="specular"; + shader_names->roughness="roughness"; + shader_names->metalness="metalness"; + shader_names->emission="emission"; + shader_names->emission_energy="emission_energy"; + shader_names->normal_scale="normal_scale"; + shader_names->rim="rim"; + shader_names->rim_tint="rim_tint"; + shader_names->clearcoat="clearcoat"; + shader_names->clearcoat_gloss="clearcoat_gloss"; + shader_names->anisotropy="anisotropy_ratio"; + shader_names->height_scale="height_scale"; + shader_names->subsurface_scattering_strength="subsurface_scattering_strength"; + shader_names->refraction="refraction"; + shader_names->refraction_roughness="refraction_roughness"; + shader_names->point_size="point_size"; + shader_names->uv1_scale="uv1_scale"; + shader_names->uv1_offset="uv1_offset"; + shader_names->uv2_scale="uv2_scale"; + shader_names->uv2_offset="uv2_offset"; + + shader_names->texture_names[TEXTURE_ALBEDO]="texture_albedo"; + shader_names->texture_names[TEXTURE_SPECULAR]="texture_specular"; + shader_names->texture_names[TEXTURE_EMISSION]="texture_emission"; + shader_names->texture_names[TEXTURE_NORMAL]="texture_normal"; + shader_names->texture_names[TEXTURE_RIM]="texture_rim"; + shader_names->texture_names[TEXTURE_CLEARCOAT]="texture_clearcoat"; + shader_names->texture_names[TEXTURE_FLOWMAP]="texture_flowmap"; + shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION]="texture_ambient_occlusion"; + shader_names->texture_names[TEXTURE_HEIGHT]="texture_height"; + shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING]="texture_subsurface_scattering"; + shader_names->texture_names[TEXTURE_REFRACTION]="texture_refraction"; + shader_names->texture_names[TEXTURE_REFRACTION_ROUGHNESS]="texture_refraction_roughness"; + shader_names->texture_names[TEXTURE_DETAIL_MASK]="texture_detail_mask"; + shader_names->texture_names[TEXTURE_DETAIL_ALBEDO]="texture_detail_albedo"; + shader_names->texture_names[TEXTURE_DETAIL_NORMAL]="texture_detail_normal"; + } +void FixedSpatialMaterial::finish_shaders(){ -void Material::set_blend_mode(BlendMode p_blend_mode) { +#ifndef NO_THREADS + memdelete( material_mutex ); +#endif + + memdelete( shader_names ); - ERR_FAIL_INDEX(p_blend_mode,4); - blend_mode=p_blend_mode; - VisualServer::get_singleton()->material_set_blend_mode(material,(VS::MaterialBlendMode)p_blend_mode); - _change_notify(); } -Material::BlendMode Material::get_blend_mode() const { - return blend_mode; + +void FixedSpatialMaterial::_update_shader() { + + dirty_materials.remove( &element ); + + MaterialKey mk = _compute_key(); + if (mk.key==current_key.key) + return; //no update required in the end + + if (shader_map.has(current_key)) { + shader_map[current_key].users--; + if (shader_map[current_key].users==0) { + //deallocate shader, as it's no longer in use + VS::get_singleton()->free(shader_map[current_key].shader); + shader_map.erase(current_key); + } + } + + current_key=mk; + + if (shader_map.has(mk)) { + + VS::get_singleton()->material_set_shader(_get_material(),shader_map[mk].shader); + shader_map[mk].users++; + return; + } + + //must create a shader! + + String code="render_mode "; + switch(blend_mode) { + case BLEND_MODE_MIX: code+="blend_mix"; break; + case BLEND_MODE_ADD: code+="blend_add"; break; + case BLEND_MODE_SUB: code+="blend_sub"; break; + case BLEND_MODE_MUL: code+="blend_mul"; break; + } + + switch(depth_draw_mode) { + case DEPTH_DRAW_OPAQUE_ONLY: code+=",depth_draw_opaque"; break; + case DEPTH_DRAW_ALWAYS: code+=",depth_draw_always"; break; + case DEPTH_DRAW_DISABLED: code+=",depth_draw_never"; break; + case DEPTH_DRAW_ALPHA_OPAQUE_PREPASS: code+=",depth_draw_alpha_prepass"; break; + } + + switch(cull_mode) { + case CULL_BACK: code+=",cull_back"; break; + case CULL_FRONT: code+=",cull_front"; break; + case CULL_DISABLED: code+=",cull_disabled"; break; + + } + + if (flags[FLAG_UNSHADED]) { + code+=",unshaded"; + } + if (flags[FLAG_ONTOP]) { + code+=",ontop"; + } + + code+=";\n"; + + + code+="uniform vec4 albedo : hint_color;\n"; + code+="uniform sampler2D texture_albedo : hint_albedo;\n"; + if (specular_mode==SPECULAR_MODE_SPECULAR) { + code+="uniform vec4 specular : hint_color;\n"; + } else { + code+="uniform float metalness;\n"; + } + + code+="uniform float roughness : hint_range(0,1);\n"; + code+="uniform float point_size : hint_range(0,128);\n"; + code+="uniform sampler2D texture_specular : hint_white;\n"; + code+="uniform vec2 uv1_scale;\n"; + code+="uniform vec2 uv1_offset;\n"; + code+="uniform vec2 uv2_scale;\n"; + code+="uniform vec2 uv2_offset;\n"; + + if (features[FEATURE_EMISSION]) { + + code+="uniform sampler2D texture_emission : hint_black_albedo;\n"; + code+="uniform vec4 emission : hint_color;\n"; + code+="uniform float emission_energy;\n"; + } + + if (features[FEATURE_NORMAL_MAPPING]) { + code+="uniform sampler2D texture_normal : hint_normal;\n"; + code+="uniform float normal_scale : hint_range(-16,16);\n"; + } + if (features[FEATURE_RIM]) { + code+="uniform float rim : hint_range(0,1);\n"; + code+="uniform float rim_tint : hint_range(0,1);\n"; + code+="uniform sampler2D texture_rim : hint_white;\n"; + } + if (features[FEATURE_CLEARCOAT]) { + code+="uniform float clearcoat : hint_range(0,1);\n"; + code+="uniform float clearcoat_gloss : hint_range(0,1);\n"; + code+="uniform sampler2D texture_clearcoat : hint_white;\n"; + } + if (features[FEATURE_ANISOTROPY]) { + code+="uniform float anisotropy_ratio : hint_range(0,256);\n"; + code+="uniform sampler2D texture_flowmap : hint_aniso;\n"; + } + if (features[FEATURE_AMBIENT_OCCLUSION]) { + code+="uniform sampler2D texture_ambient_occlusion : hint_white;\n"; + } + + if (features[FEATURE_DETAIL]) { + code+="uniform sampler2D texture_detail_albedo : hint_albedo;\n"; + code+="uniform sampler2D texture_detail_normal : hint_normal;\n"; + code+="uniform sampler2D texture_detail_mask : hint_white;\n"; + } + + if (features[FEATURE_SUBSURACE_SCATTERING]) { + + code+="uniform float subsurface_scattering_strength : hint_range(0,1);\n"; + code+="uniform sampler2D texture_subsurface_scattering : hint_white;\n"; + + } + + + code+="\n\n"; + + code+="void vertex() {\n"; + + if (flags[FLAG_SRGB_VERTEX_COLOR]) { + + code+="\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n"; + } + if (flags[FLAG_USE_POINT_SIZE]) { + + code+="\tPOINT_SIZE=point_size;\n"; + } + code+="\tUV=UV*uv1_scale+uv1_offset;\n"; + if (detail_uv==DETAIL_UV_2) { + code+="\tUV2=UV2*uv2_scale+uv2_offset;\n"; + } + + code+="}\n"; + code+="\n\n"; + code+="void fragment() {\n"; + + if (flags[FLAG_USE_POINT_SIZE]) { + code+="\tvec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n"; + } else { + code+="\tvec4 albedo_tex = texture(texture_albedo,UV);\n"; + } + + if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) { + code+="\talbedo_tex *= COLOR;\n"; + } + + code+="\tALBEDO = albedo.rgb * albedo_tex.rgb;\n"; + if (features[FEATURE_TRANSPARENT]) { + code+="\tALPHA = albedo.a * albedo_tex.a;\n"; + } + + if (features[FEATURE_EMISSION]) { + code+="\tEMISSION = (emission.rgb+texture(texture_emission,UV).rgb)*emission_energy;\n"; + } + + if (features[FEATURE_NORMAL_MAPPING]) { + code+="\tNORMALMAP = texture(texture_normal,UV).rgb;\n"; + code+="\tNORMALMAP_DEPTH = normal_scale;\n"; + } + + if (features[FEATURE_RIM]) { + code+="\tvec2 rim_tex = texture(texture_rim,UV).xw;\n"; + code+="\tRIM = rim*rim_tex.x;"; + code+="\tRIM_TINT = rim_tint*rim_tex.y;\n"; + } + + if (features[FEATURE_CLEARCOAT]) { + code+="\tvec2 clearcoat_tex = texture(texture_clearcoat,UV).xw;\n"; + code+="\tCLEARCOAT = clearcoat*clearcoat_tex.x;"; + code+="\tCLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n"; + } + + if (features[FEATURE_ANISOTROPY]) { + code+="\tvec4 anisotropy_tex = texture(texture_flowmap,UV);\n"; + code+="\tANISOTROPY = anisotropy_ratio*anisotropy_tex.a;\n"; + code+="\tANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n"; + } + + if (features[FEATURE_AMBIENT_OCCLUSION]) { + code+="\tAO = texture(texture_ambient_occlusion,UV).r;\n"; + } + + if (features[FEATURE_SUBSURACE_SCATTERING]) { + + code+="\tfloat sss_tex = texture(texture_subsurface_scattering,UV).r;\n"; + code+="\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n"; + } + + if (features[FEATURE_DETAIL]) { + String det_uv=detail_uv==DETAIL_UV_1?"UV":"UV2"; + code+="\tvec4 detail_tex = texture(texture_detail_albedo,"+det_uv+");\n"; + code+="\tvec4 detail_norm_tex = texture(texture_detail_normal,"+det_uv+");\n"; + code+="\tvec4 detail_mask_tex = texture(texture_detail_mask,UV);\n"; + + switch(detail_blend_mode) { + case BLEND_MODE_MIX: { + code+="\tvec3 detail = mix(ALBEDO.rgb,detail_tex.rgb,detail_tex.a);\n"; + } break; + case BLEND_MODE_ADD: { + code+="\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb+detail_tex.rgb,detail_tex.a);\n"; + } break; + case BLEND_MODE_SUB: { + code+="\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb-detail_tex.rgb,detail_tex.a);\n"; + } break; + case BLEND_MODE_MUL: { + code+="\tvec3 detail = mix(ALBEDO.rgb,ALBEDO.rgb*detail_tex.rgb,detail_tex.a);\n"; + } break; + + } + + code+="\tvec3 detail_norm = mix(NORMALMAP,detail_norm_tex.rgb,detail_tex.a);\n"; + + code+="\tNORMALMAP = mix(NORMALMAP,detail_norm,detail_mask_tex.r);\n"; + code+="\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n"; + } + + if (specular_mode==SPECULAR_MODE_SPECULAR) { + + code+="\tvec4 specular_tex = texture(texture_specular,UV);\n"; + code+="\tSPECULAR = specular.rgb * specular_tex.rgb;\n"; + code+="\tROUGHNESS = specular_tex.a * roughness;\n"; + } else { + code+="\tvec4 specular_tex = texture(texture_specular,UV);\n"; + code+="\tSPECULAR = vec3(metalness * specular_tex.r);\n"; + code+="\tROUGHNESS = specular_tex.a * roughness;\n"; + } + + code+="}\n"; + + ShaderData shader_data; + shader_data.shader = VS::get_singleton()->shader_create(VS::SHADER_SPATIAL); + shader_data.users=1; + + VS::get_singleton()->shader_set_code( shader_data.shader, code ); + + shader_map[mk]=shader_data; + + VS::get_singleton()->material_set_shader(_get_material(),shader_data.shader); + } +void FixedSpatialMaterial::flush_changes() { -void Material::set_depth_draw_mode(DepthDrawMode p_depth_draw_mode) { + if (material_mutex) + material_mutex->lock(); - depth_draw_mode=p_depth_draw_mode; - VisualServer::get_singleton()->material_set_depth_draw_mode(material,(VS::MaterialDepthDrawMode)p_depth_draw_mode); + while (dirty_materials.first()) { + + dirty_materials.first()->self()->_update_shader(); + } + + if (material_mutex) + material_mutex->unlock(); } -Material::DepthDrawMode Material::get_depth_draw_mode() const { +void FixedSpatialMaterial::_queue_shader_change() { + + if (material_mutex) + material_mutex->lock(); + + if (!element.in_list()) { + dirty_materials.add(&element); + } + + if (material_mutex) + material_mutex->unlock(); + - return depth_draw_mode; } -bool Material::get_flag(Flag p_flag) const { +bool FixedSpatialMaterial::_is_shader_dirty() const { - ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false); - return flags[p_flag]; + bool dirty=false; + + if (material_mutex) + material_mutex->lock(); + + dirty=element.in_list(); + + if (material_mutex) + material_mutex->unlock(); + + return dirty; } +void FixedSpatialMaterial::set_albedo(const Color& p_albedo) { -void Material::set_line_width(float p_width) { + albedo=p_albedo; - line_width=p_width; - VisualServer::get_singleton()->material_set_line_width(material,p_width); - _change_notify("line_width"); + VS::get_singleton()->material_set_param(_get_material(),shader_names->albedo,p_albedo); } -float Material::get_line_width() const { +Color FixedSpatialMaterial::get_albedo() const{ - return line_width; + return albedo; } +void FixedSpatialMaterial::set_specular_mode(SpecularMode p_mode) { + specular_mode=p_mode; + _change_notify(); + _queue_shader_change(); +} -void Material::_bind_methods() { +FixedSpatialMaterial::SpecularMode FixedSpatialMaterial::get_specular_mode() const { - ObjectTypeDB::bind_method(_MD("set_flag","flag","enable"),&Material::set_flag); - ObjectTypeDB::bind_method(_MD("get_flag","flag"),&Material::get_flag); - ObjectTypeDB::bind_method(_MD("set_blend_mode","mode"),&Material::set_blend_mode); - ObjectTypeDB::bind_method(_MD("get_blend_mode"),&Material::get_blend_mode); - ObjectTypeDB::bind_method(_MD("set_line_width","width"),&Material::set_line_width); - ObjectTypeDB::bind_method(_MD("get_line_width"),&Material::get_line_width); - ObjectTypeDB::bind_method(_MD("set_depth_draw_mode","mode"),&Material::set_depth_draw_mode); - ObjectTypeDB::bind_method(_MD("get_depth_draw_mode"),&Material::get_depth_draw_mode); + return specular_mode; +} +void FixedSpatialMaterial::set_specular(const Color& p_specular){ - for(int i=0;i<FLAG_MAX;i++) - ADD_PROPERTYI( PropertyInfo( Variant::BOOL, String()+"flags/"+_flag_names[i] ),_SCS("set_flag"),_SCS("get_flag"),_flag_indices[i]); + specular=p_specular; + VS::get_singleton()->material_set_param(_get_material(),shader_names->specular,p_specular); - ADD_PROPERTY( PropertyInfo( Variant::INT, "params/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,PMAlpha" ), _SCS("set_blend_mode"),_SCS("get_blend_mode")); - ADD_PROPERTY( PropertyInfo( Variant::INT, "params/depth_draw",PROPERTY_HINT_ENUM,"Always,Opaque Only,Pre-Pass Alpha,Never" ), _SCS("set_depth_draw_mode"),_SCS("get_depth_draw_mode")); - ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/line_width",PROPERTY_HINT_RANGE,"0.1,32.0,0.1" ), _SCS("set_line_width"),_SCS("get_line_width")); +} +Color FixedSpatialMaterial::get_specular() const{ - BIND_CONSTANT( FLAG_VISIBLE ); - BIND_CONSTANT( FLAG_DOUBLE_SIDED ); - BIND_CONSTANT( FLAG_INVERT_FACES ); - BIND_CONSTANT( FLAG_UNSHADED ); - BIND_CONSTANT( FLAG_ONTOP ); - BIND_CONSTANT( FLAG_LIGHTMAP_ON_UV2 ); - BIND_CONSTANT( FLAG_COLOR_ARRAY_SRGB ); - BIND_CONSTANT( FLAG_MAX ); + return specular; +} - BIND_CONSTANT( DEPTH_DRAW_ALWAYS ); - BIND_CONSTANT( DEPTH_DRAW_OPAQUE_ONLY ); - BIND_CONSTANT( DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA ); - BIND_CONSTANT( DEPTH_DRAW_NEVER ); +void FixedSpatialMaterial::set_roughness(float p_roughness){ - BIND_CONSTANT( BLEND_MODE_MIX ); - BIND_CONSTANT( BLEND_MODE_ADD ); - BIND_CONSTANT( BLEND_MODE_SUB ); - BIND_CONSTANT( BLEND_MODE_MUL ); - BIND_CONSTANT( BLEND_MODE_PREMULT_ALPHA ); + roughness=p_roughness; + VS::get_singleton()->material_set_param(_get_material(),shader_names->roughness,p_roughness); } -Material::Material(const RID& p_material) { - material=p_material; +float FixedSpatialMaterial::get_roughness() const{ - flags[FLAG_VISIBLE]=true; - flags[FLAG_DOUBLE_SIDED]=false; - flags[FLAG_INVERT_FACES]=false; - flags[FLAG_UNSHADED]=false; - flags[FLAG_ONTOP]=false; - flags[FLAG_LIGHTMAP_ON_UV2]=true; - flags[FLAG_COLOR_ARRAY_SRGB]=false; + return roughness; +} - depth_draw_mode=DEPTH_DRAW_OPAQUE_ONLY; +void FixedSpatialMaterial::set_metalness(float p_metalness){ + + metalness=p_metalness; + VS::get_singleton()->material_set_param(_get_material(),shader_names->metalness,p_metalness); +} - blend_mode=BLEND_MODE_MIX; +float FixedSpatialMaterial::get_metalness() const{ + + return metalness; } -Material::~Material() { +void FixedSpatialMaterial::set_emission(const Color& p_emission){ + + emission=p_emission; + VS::get_singleton()->material_set_param(_get_material(),shader_names->emission,p_emission); - VisualServer::get_singleton()->free(material); } +Color FixedSpatialMaterial::get_emission() const{ -static const char*_param_names[FixedMaterial::PARAM_MAX]={ - "diffuse", - "detail", - "specular", - "emission", - "specular_exp", - "glow", - "normal", - "shade_param" -}; - -static const char*_full_param_names[FixedMaterial::PARAM_MAX]={ - "params/diffuse", - "params/detail", - "params/specular", - "params/emission", - "params/specular_exp", - "params/glow", - "params/normal", - "params/shade_param" -}; - -/* -static const char*_texture_param_names[FixedMaterial::PARAM_MAX]={ - "tex_diffuse", - "tex_detail", - "tex_specular", - "tex_emission", - "tex_specular_exp", - "tex_glow", - "tex_detail_mix", - "tex_normal", - "tex_shade_param" -}; -*/ -static const FixedMaterial::Parameter _param_indices[FixedMaterial::PARAM_MAX]={ - FixedMaterial::PARAM_DIFFUSE, - FixedMaterial::PARAM_DETAIL, - FixedMaterial::PARAM_SPECULAR, - FixedMaterial::PARAM_EMISSION, - FixedMaterial::PARAM_SPECULAR_EXP, - FixedMaterial::PARAM_GLOW, - FixedMaterial::PARAM_NORMAL, - FixedMaterial::PARAM_SHADE_PARAM, -}; - - - - -void FixedMaterial::set_parameter(Parameter p_parameter, const Variant& p_value) { - - ERR_FAIL_INDEX(p_parameter,PARAM_MAX); - if ((p_parameter==PARAM_DIFFUSE || p_parameter==PARAM_SPECULAR || p_parameter==PARAM_EMISSION)) { - - if (p_value.get_type()!=Variant::COLOR) { - ERR_EXPLAIN(String(_param_names[p_parameter])+" expects Color"); - ERR_FAIL(); - } - } else { + return emission; +} - if (!p_value.is_num()) { - ERR_EXPLAIN(String(_param_names[p_parameter])+" expects scalar"); - ERR_FAIL(); - } - } - ERR_FAIL_COND( (p_parameter==PARAM_DIFFUSE || p_parameter==PARAM_SPECULAR || p_parameter==PARAM_EMISSION) && p_value.get_type()!=Variant::COLOR ); - ERR_FAIL_COND( p_parameter!=PARAM_SHADE_PARAM && p_parameter!=PARAM_DIFFUSE && p_parameter!=PARAM_DETAIL && p_parameter!=PARAM_SPECULAR && p_parameter!=PARAM_EMISSION && p_value.get_type()!=Variant::REAL && p_value.get_type()!=Variant::INT ); +void FixedSpatialMaterial::set_emission_energy(float p_emission_energy){ - param[p_parameter]=p_value; + emission_energy=p_emission_energy; + VS::get_singleton()->material_set_param(_get_material(),shader_names->emission_energy,p_emission_energy); - VisualServer::get_singleton()->fixed_material_set_param(material,(VS::FixedMaterialParam)p_parameter,p_value); +} +float FixedSpatialMaterial::get_emission_energy() const{ - _change_notify(_full_param_names[p_parameter]); + return emission_energy; } -Variant FixedMaterial::get_parameter(Parameter p_parameter) const { - ERR_FAIL_INDEX_V(p_parameter,PARAM_MAX,Variant()); - return param[p_parameter]; +void FixedSpatialMaterial::set_normal_scale(float p_normal_scale){ + + normal_scale=p_normal_scale; + VS::get_singleton()->material_set_param(_get_material(),shader_names->normal_scale,p_normal_scale); + } +float FixedSpatialMaterial::get_normal_scale() const{ + return normal_scale; +} +void FixedSpatialMaterial::set_rim(float p_rim){ -void FixedMaterial::set_texture(Parameter p_parameter, Ref<Texture> p_texture) { + rim=p_rim; + VS::get_singleton()->material_set_param(_get_material(),shader_names->rim,p_rim); - ERR_FAIL_INDEX(p_parameter,PARAM_MAX); - texture_param[p_parameter]=p_texture; - VisualServer::get_singleton()->fixed_material_set_texture(material,(VS::FixedMaterialParam)p_parameter,p_texture.is_null()?RID():p_texture->get_rid()); +} +float FixedSpatialMaterial::get_rim() const{ - _change_notify(); + return rim; } -Ref<Texture> FixedMaterial::get_texture(Parameter p_parameter) const { - ERR_FAIL_INDEX_V(p_parameter,PARAM_MAX,Ref<Texture>()); - return texture_param[p_parameter]; +void FixedSpatialMaterial::set_rim_tint(float p_rim_tint){ + + rim_tint=p_rim_tint; + VS::get_singleton()->material_set_param(_get_material(),shader_names->rim_tint,p_rim_tint); + } +float FixedSpatialMaterial::get_rim_tint() const{ -void FixedMaterial::set_texcoord_mode(Parameter p_parameter, TexCoordMode p_mode) { + return rim_tint; +} - ERR_FAIL_INDEX(p_parameter,PARAM_MAX); - ERR_FAIL_INDEX(p_mode,4); +void FixedSpatialMaterial::set_clearcoat(float p_clearcoat){ - if (p_mode==texture_texcoord[p_parameter]) - return; + clearcoat=p_clearcoat; + VS::get_singleton()->material_set_param(_get_material(),shader_names->clearcoat,p_clearcoat); - texture_texcoord[p_parameter]=p_mode; +} - VisualServer::get_singleton()->fixed_material_set_texcoord_mode(material,(VS::FixedMaterialParam)p_parameter,(VS::FixedMaterialTexCoordMode)p_mode); +float FixedSpatialMaterial::get_clearcoat() const{ - _change_notify(); + return clearcoat; } -FixedMaterial::TexCoordMode FixedMaterial::get_texcoord_mode(Parameter p_parameter) const { +void FixedSpatialMaterial::set_clearcoat_gloss(float p_clearcoat_gloss){ + + clearcoat_gloss=p_clearcoat_gloss; + VS::get_singleton()->material_set_param(_get_material(),shader_names->clearcoat_gloss,p_clearcoat_gloss); + - ERR_FAIL_INDEX_V(p_parameter,PARAM_MAX,TEXCOORD_UV); - return texture_texcoord[p_parameter]; } -void FixedMaterial::set_light_shader(LightShader p_shader) { +float FixedSpatialMaterial::get_clearcoat_gloss() const{ - light_shader=p_shader; - VS::get_singleton()->fixed_material_set_light_shader(material,VS::FixedMaterialLightShader(p_shader)); + return clearcoat_gloss; } -FixedMaterial::LightShader FixedMaterial::get_light_shader() const { +void FixedSpatialMaterial::set_anisotropy(float p_anisotropy){ + + anisotropy=p_anisotropy; + VS::get_singleton()->material_set_param(_get_material(),shader_names->anisotropy,p_anisotropy); + +} +float FixedSpatialMaterial::get_anisotropy() const{ - return light_shader; + return anisotropy; } +void FixedSpatialMaterial::set_height_scale(float p_height_scale){ + + height_scale=p_height_scale; + VS::get_singleton()->material_set_param(_get_material(),shader_names->height_scale,p_height_scale); -void FixedMaterial::set_uv_transform(const Transform& p_transform) { - uv_transform=p_transform; - VisualServer::get_singleton()->fixed_material_set_uv_transform(material, p_transform ); - _change_notify(); } -Transform FixedMaterial::get_uv_transform() const { +float FixedSpatialMaterial::get_height_scale() const{ - return uv_transform; + return height_scale; } +void FixedSpatialMaterial::set_subsurface_scattering_strength(float p_subsurface_scattering_strength){ + subsurface_scattering_strength=p_subsurface_scattering_strength; + VS::get_singleton()->material_set_param(_get_material(),shader_names->subsurface_scattering_strength,subsurface_scattering_strength); -void FixedMaterial::set_fixed_flag(FixedFlag p_flag, bool p_value) { - ERR_FAIL_INDEX(p_flag,5); - fixed_flags[p_flag]=p_value; - VisualServer::get_singleton()->fixed_material_set_flag(material,(VS::FixedMaterialFlags)p_flag,p_value); +} + +float FixedSpatialMaterial::get_subsurface_scattering_strength() const{ + return subsurface_scattering_strength; } -bool FixedMaterial::get_fixed_flag(FixedFlag p_flag) const { - ERR_FAIL_INDEX_V(p_flag,5,false); - return fixed_flags[p_flag]; +void FixedSpatialMaterial::set_refraction(float p_refraction){ + + refraction=p_refraction; + VS::get_singleton()->material_set_param(_get_material(),shader_names->refraction,refraction); + } -void FixedMaterial::set_point_size(float p_size) { +float FixedSpatialMaterial::get_refraction() const { - ERR_FAIL_COND(p_size<0); - point_size=p_size; - VisualServer::get_singleton()->fixed_material_set_point_size(material,p_size); + return refraction; } -float FixedMaterial::get_point_size() const{ +void FixedSpatialMaterial::set_refraction_roughness(float p_refraction_roughness) { + + refraction_roughness=p_refraction_roughness; + VS::get_singleton()->material_set_param(_get_material(),shader_names->refraction_roughness,refraction_roughness); - return point_size; } +float FixedSpatialMaterial::get_refraction_roughness() const { + return refraction_roughness; +} -void FixedMaterial::_bind_methods() { +void FixedSpatialMaterial::set_detail_uv(DetailUV p_detail_uv) { + if (detail_uv==p_detail_uv) + return; - ObjectTypeDB::bind_method(_MD("set_parameter","param","value"),&FixedMaterial::set_parameter); - ObjectTypeDB::bind_method(_MD("get_parameter","param"),&FixedMaterial::get_parameter); + detail_uv=p_detail_uv; + _queue_shader_change(); +} +FixedSpatialMaterial::DetailUV FixedSpatialMaterial::get_detail_uv() const { - ObjectTypeDB::bind_method(_MD("set_texture","param","texture:Texture"),&FixedMaterial::set_texture); - ObjectTypeDB::bind_method(_MD("get_texture:Texture","param"),&FixedMaterial::get_texture); + return detail_uv; +} +void FixedSpatialMaterial::set_blend_mode(BlendMode p_mode) { - ObjectTypeDB::bind_method(_MD("set_texcoord_mode","param","mode"),&FixedMaterial::set_texcoord_mode); - ObjectTypeDB::bind_method(_MD("get_texcoord_mode","param"),&FixedMaterial::get_texcoord_mode); + if (blend_mode==p_mode) + return; - ObjectTypeDB::bind_method(_MD("set_fixed_flag","flag","value"),&FixedMaterial::set_fixed_flag); - ObjectTypeDB::bind_method(_MD("get_fixed_flag","flag"),&FixedMaterial::get_fixed_flag); + blend_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::BlendMode FixedSpatialMaterial::get_blend_mode() const { - ObjectTypeDB::bind_method(_MD("set_uv_transform","transform"),&FixedMaterial::set_uv_transform); - ObjectTypeDB::bind_method(_MD("get_uv_transform"),&FixedMaterial::get_uv_transform); + return blend_mode; +} - ObjectTypeDB::bind_method(_MD("set_light_shader","shader"),&FixedMaterial::set_light_shader); - ObjectTypeDB::bind_method(_MD("get_light_shader"),&FixedMaterial::get_light_shader); +void FixedSpatialMaterial::set_detail_blend_mode(BlendMode p_mode) { - ObjectTypeDB::bind_method(_MD("set_point_size","size"),&FixedMaterial::set_point_size); - ObjectTypeDB::bind_method(_MD("get_point_size"),&FixedMaterial::get_point_size); + detail_blend_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::BlendMode FixedSpatialMaterial::get_detail_blend_mode() const { + return detail_blend_mode; +} - ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_alpha" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_ALPHA); - ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_color_array" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_COLOR_ARRAY); - ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_point_size" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_POINT_SIZE); - ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/discard_alpha" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_DISCARD_ALPHA); - ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_xy_normalmap" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_XY_NORMALMAP); - ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/diffuse" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_DIFFUSE); - ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/specular", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPECULAR ); - ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/emission", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_EMISSION ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/specular_exp", PROPERTY_HINT_RANGE,"1,64,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPECULAR_EXP ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/detail_mix", PROPERTY_HINT_RANGE,"0,1,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_DETAIL ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/normal_depth", PROPERTY_HINT_RANGE,"-4,4,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_NORMAL ); - ADD_PROPERTY( PropertyInfo( Variant::INT, "params/shader", PROPERTY_HINT_ENUM,"Lambert,Wrap,Velvet,Toon" ), _SCS("set_light_shader"), _SCS("get_light_shader") ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/shader_param", PROPERTY_HINT_RANGE,"0,1,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADE_PARAM ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/glow", PROPERTY_HINT_RANGE,"0,8,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_GLOW ); - ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/point_size", PROPERTY_HINT_RANGE,"0,1024,1" ), _SCS("set_point_size"), _SCS("get_point_size")); - ADD_PROPERTY( PropertyInfo( Variant::TRANSFORM, "uv_xform"), _SCS("set_uv_transform"), _SCS("get_uv_transform") ); +void FixedSpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) { - for(int i=0;i<PARAM_MAX;i++) { - ADD_PROPERTYI( PropertyInfo( Variant::OBJECT, String()+"textures/"+_param_names[i],PROPERTY_HINT_RESOURCE_TYPE,"Texture" ), _SCS("set_texture"), _SCS("get_texture"), _param_indices[i]); - ADD_PROPERTYI( PropertyInfo( Variant::INT, String()+"textures/"+_param_names[i]+"_tc",PROPERTY_HINT_ENUM,"UV,UV Xform,UV2,Sphere" ), _SCS("set_texcoord_mode"), _SCS("get_texcoord_mode"), _param_indices[i] ); - } + if (depth_draw_mode==p_mode) + return; + depth_draw_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::DepthDrawMode FixedSpatialMaterial::get_depth_draw_mode() const { - BIND_CONSTANT( PARAM_DIFFUSE ); - BIND_CONSTANT( PARAM_DETAIL ); - BIND_CONSTANT( PARAM_SPECULAR ); - BIND_CONSTANT( PARAM_EMISSION ); - BIND_CONSTANT( PARAM_SPECULAR_EXP ); - BIND_CONSTANT( PARAM_GLOW ); - BIND_CONSTANT( PARAM_NORMAL ); - BIND_CONSTANT( PARAM_SHADE_PARAM ); - BIND_CONSTANT( PARAM_MAX ); + return depth_draw_mode; +} - BIND_CONSTANT( TEXCOORD_UV ); - BIND_CONSTANT( TEXCOORD_UV_TRANSFORM ); - BIND_CONSTANT( TEXCOORD_UV2 ); - BIND_CONSTANT( TEXCOORD_SPHERE ); +void FixedSpatialMaterial::set_cull_mode(CullMode p_mode) { - BIND_CONSTANT( FLAG_USE_ALPHA ); - BIND_CONSTANT( FLAG_USE_COLOR_ARRAY ); - BIND_CONSTANT( FLAG_USE_POINT_SIZE ); - BIND_CONSTANT( FLAG_DISCARD_ALPHA ); + if (cull_mode==p_mode) + return; - BIND_CONSTANT( LIGHT_SHADER_LAMBERT ); - BIND_CONSTANT( LIGHT_SHADER_WRAP ); - BIND_CONSTANT( LIGHT_SHADER_VELVET ); - BIND_CONSTANT( LIGHT_SHADER_TOON ); + cull_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::CullMode FixedSpatialMaterial::get_cull_mode() const { + return cull_mode; } +void FixedSpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) { -FixedMaterial::FixedMaterial() : Material(VS::get_singleton()->fixed_material_create()) { + if (diffuse_mode==p_mode) + return; + diffuse_mode=p_mode; + _queue_shader_change(); +} +FixedSpatialMaterial::DiffuseMode FixedSpatialMaterial::get_diffuse_mode() const { + return diffuse_mode; +} - param[PARAM_DIFFUSE]=Color(1,1,1); - param[PARAM_SPECULAR]=Color(0.0,0.0,0.0); - param[PARAM_EMISSION]=Color(0.0,0.0,0.0); - param[PARAM_SPECULAR_EXP]=40; - param[PARAM_GLOW]=0; - param[PARAM_NORMAL]=1; - param[PARAM_SHADE_PARAM]=0.5; - param[PARAM_DETAIL]=1.0; +void FixedSpatialMaterial::set_flag(Flags p_flag,bool p_enabled) { - set_flag(FLAG_COLOR_ARRAY_SRGB,true); + ERR_FAIL_INDEX(p_flag,FLAG_MAX); - fixed_flags[FLAG_USE_ALPHA]=false; - fixed_flags[FLAG_USE_COLOR_ARRAY]=false; - fixed_flags[FLAG_USE_POINT_SIZE]=false; - fixed_flags[FLAG_USE_XY_NORMALMAP]=false; - fixed_flags[FLAG_DISCARD_ALPHA]=false; + if (flags[p_flag]==p_enabled) + return; + flags[p_flag]=p_enabled; + _queue_shader_change(); +} - for(int i=0;i<PARAM_MAX;i++) { +bool FixedSpatialMaterial::get_flag(Flags p_flag) const { - texture_texcoord[i]=TEXCOORD_UV; - } + ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false); + return flags[p_flag]; +} - light_shader=LIGHT_SHADER_LAMBERT; +void FixedSpatialMaterial::set_feature(Feature p_feature,bool p_enabled) { - point_size=1.0; -} + ERR_FAIL_INDEX(p_feature,FEATURE_MAX); + if (features[p_feature]==p_enabled) + return; + features[p_feature]=p_enabled; + _change_notify(); + _queue_shader_change(); -FixedMaterial::~FixedMaterial() { } +bool FixedSpatialMaterial::get_feature(Feature p_feature) const { + ERR_FAIL_INDEX_V(p_feature,FEATURE_MAX,false); + return features[p_feature]; +} -bool ShaderMaterial::_set(const StringName& p_name, const Variant& p_value) { - if (p_name==SceneStringNames::get_singleton()->shader_shader) { - set_shader(p_value); - return true; - } else { +void FixedSpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_texture) { - if (shader.is_valid()) { + ERR_FAIL_INDEX(p_param,TEXTURE_MAX); + textures[p_param]=p_texture; + RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + VS::get_singleton()->material_set_param(_get_material(),shader_names->texture_names[p_param],rid); +} +Ref<Texture> FixedSpatialMaterial::get_texture(TextureParam p_param) const { - StringName pr = shader->remap_param(p_name); - if (!pr) { - String n = p_name; - if (n.find("param/")==0) { //backwards compatibility - pr = n.substr(6,n.length()); - } - } - if (pr) { - VisualServer::get_singleton()->material_set_param(material,pr,p_value); - return true; - } - } + ERR_FAIL_INDEX_V(p_param,TEXTURE_MAX,Ref<Texture>()); + return textures[p_param]; +} + + +void FixedSpatialMaterial::_validate_feature(const String& text, Feature feature,PropertyInfo& property) const { + if (property.name.begins_with(text) && property.name!=text+"/enabled" && !features[feature]) { + property.usage=0; } - return false; } -bool ShaderMaterial::_get(const StringName& p_name,Variant &r_ret) const { - +void FixedSpatialMaterial::_validate_property(PropertyInfo& property) const { + _validate_feature("normal",FEATURE_NORMAL_MAPPING,property); + _validate_feature("emission",FEATURE_EMISSION,property); + _validate_feature("rim",FEATURE_RIM,property); + _validate_feature("clearcoat",FEATURE_CLEARCOAT,property); + _validate_feature("anisotropy",FEATURE_ANISOTROPY,property); + _validate_feature("ao",FEATURE_AMBIENT_OCCLUSION,property); + _validate_feature("height",FEATURE_HEIGHT_MAPPING,property); + _validate_feature("subsurf_scatter",FEATURE_SUBSURACE_SCATTERING,property); + _validate_feature("refraction",FEATURE_REFRACTION,property); + _validate_feature("detail",FEATURE_DETAIL,property); + + if (property.name=="specular/color" && specular_mode==SPECULAR_MODE_METALLIC) { + property.usage=0; + } + if (property.name=="specular/metalness" && specular_mode==SPECULAR_MODE_SPECULAR) { + property.usage=0; + } - if (p_name==SceneStringNames::get_singleton()->shader_shader) { +} - r_ret=get_shader(); - return true; - } else { +void FixedSpatialMaterial::set_line_width(float p_line_width) { - if (shader.is_valid()) { + line_width=p_line_width; + VS::get_singleton()->material_set_line_width(_get_material(),line_width); +} - StringName pr = shader->remap_param(p_name); - if (pr) { - r_ret=VisualServer::get_singleton()->material_get_param(material,pr); - return true; - } - } +float FixedSpatialMaterial::get_line_width() const { - } + return line_width; +} +void FixedSpatialMaterial::set_point_size(float p_point_size) { - return false; + point_size=p_point_size; + VS::get_singleton()->material_set_param(_get_material(),shader_names->point_size,p_point_size); } +float FixedSpatialMaterial::get_point_size() const { -void ShaderMaterial::_get_property_list( List<PropertyInfo> *p_list) const { + return point_size; +} - p_list->push_back( PropertyInfo( Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE,"MaterialShader,MaterialShaderGraph" ) ); - if (!shader.is_null()) { +void FixedSpatialMaterial::set_uv1_scale(const Vector2& p_scale) { - shader->get_param_list(p_list); - } + uv1_scale=p_scale; + VS::get_singleton()->material_set_param(_get_material(),shader_names->uv1_scale,p_scale); +} +Vector2 FixedSpatialMaterial::get_uv1_scale() const{ + + return uv1_scale; } +void FixedSpatialMaterial::set_uv1_offset(const Vector2& p_offset){ -void ShaderMaterial::_shader_changed() { + uv1_offset=p_offset; + VS::get_singleton()->material_set_param(_get_material(),shader_names->uv1_offset,p_offset); - _change_notify(); //also all may have changed then } +Vector2 FixedSpatialMaterial::get_uv1_offset() const{ -void ShaderMaterial::set_shader(const Ref<Shader>& p_shader) { + return uv1_offset; +} - ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_MATERIAL); - if (shader.is_valid()) - shader->disconnect(SceneStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_shader_changed); - shader=p_shader; - VS::get_singleton()->material_set_shader(material,shader.is_valid()?shader->get_rid():RID()); - if (shader.is_valid()) { - shader->connect(SceneStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_shader_changed); - } - _change_notify(); +void FixedSpatialMaterial::set_uv2_scale(const Vector2& p_scale) { + uv2_scale=p_scale; + VS::get_singleton()->material_set_param(_get_material(),shader_names->uv2_scale,p_scale); } -Ref<Shader> ShaderMaterial::get_shader() const { +Vector2 FixedSpatialMaterial::get_uv2_scale() const{ - return shader; + return uv2_scale; } +void FixedSpatialMaterial::set_uv2_offset(const Vector2& p_offset){ -void ShaderMaterial::set_shader_param(const StringName& p_param,const Variant& p_value) { - - VisualServer::get_singleton()->material_set_param(material,p_param,p_value); + uv2_offset=p_offset; + VS::get_singleton()->material_set_param(_get_material(),shader_names->uv2_offset,p_offset); } -Variant ShaderMaterial::get_shader_param(const StringName& p_param) const{ +Vector2 FixedSpatialMaterial::get_uv2_offset() const{ - return VisualServer::get_singleton()->material_get_param(material,p_param); + return uv2_offset; } +void FixedSpatialMaterial::_bind_methods() { -void ShaderMaterial::_bind_methods() { + ObjectTypeDB::bind_method(_MD("set_albedo","albedo"),&FixedSpatialMaterial::set_albedo); + ObjectTypeDB::bind_method(_MD("get_albedo"),&FixedSpatialMaterial::get_albedo); - 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_specular_mode","specular_mode"),&FixedSpatialMaterial::set_specular_mode); + ObjectTypeDB::bind_method(_MD("get_specular_mode"),&FixedSpatialMaterial::get_specular_mode); - ObjectTypeDB::bind_method(_MD("set_shader_param","param","value:Variant"), &ShaderMaterial::set_shader_param); - ObjectTypeDB::bind_method(_MD("get_shader_param:Variant","param"), &ShaderMaterial::get_shader_param); + ObjectTypeDB::bind_method(_MD("set_specular","specular"),&FixedSpatialMaterial::set_specular); + ObjectTypeDB::bind_method(_MD("get_specular"),&FixedSpatialMaterial::get_specular); - ObjectTypeDB::bind_method(_MD("_shader_changed"), &ShaderMaterial::_shader_changed ); -} + ObjectTypeDB::bind_method(_MD("set_metalness","metalness"),&FixedSpatialMaterial::set_metalness); + ObjectTypeDB::bind_method(_MD("get_metalness"),&FixedSpatialMaterial::get_metalness); + ObjectTypeDB::bind_method(_MD("set_roughness","roughness"),&FixedSpatialMaterial::set_roughness); + ObjectTypeDB::bind_method(_MD("get_roughness"),&FixedSpatialMaterial::get_roughness); -void ShaderMaterial::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const { + ObjectTypeDB::bind_method(_MD("set_emission","emission"),&FixedSpatialMaterial::set_emission); + ObjectTypeDB::bind_method(_MD("get_emission"),&FixedSpatialMaterial::get_emission); - String f = p_function.operator String(); - if ((f=="get_shader_param" || f=="set_shader_param") && p_idx==0) { + ObjectTypeDB::bind_method(_MD("set_emission_energy","emission_energy"),&FixedSpatialMaterial::set_emission_energy); + ObjectTypeDB::bind_method(_MD("get_emission_energy"),&FixedSpatialMaterial::get_emission_energy); + + ObjectTypeDB::bind_method(_MD("set_normal_scale","normal_scale"),&FixedSpatialMaterial::set_normal_scale); + ObjectTypeDB::bind_method(_MD("get_normal_scale"),&FixedSpatialMaterial::get_normal_scale); + + ObjectTypeDB::bind_method(_MD("set_rim","rim"),&FixedSpatialMaterial::set_rim); + ObjectTypeDB::bind_method(_MD("get_rim"),&FixedSpatialMaterial::get_rim); + + ObjectTypeDB::bind_method(_MD("set_rim_tint","rim_tint"),&FixedSpatialMaterial::set_rim_tint); + ObjectTypeDB::bind_method(_MD("get_rim_tint"),&FixedSpatialMaterial::get_rim_tint); + + ObjectTypeDB::bind_method(_MD("set_clearcoat","clearcoat"),&FixedSpatialMaterial::set_clearcoat); + ObjectTypeDB::bind_method(_MD("get_clearcoat"),&FixedSpatialMaterial::get_clearcoat); + + ObjectTypeDB::bind_method(_MD("set_clearcoat_gloss","clearcoat_gloss"),&FixedSpatialMaterial::set_clearcoat_gloss); + ObjectTypeDB::bind_method(_MD("get_clearcoat_gloss"),&FixedSpatialMaterial::get_clearcoat_gloss); + + ObjectTypeDB::bind_method(_MD("set_anisotropy","anisotropy"),&FixedSpatialMaterial::set_anisotropy); + ObjectTypeDB::bind_method(_MD("get_anisotropy"),&FixedSpatialMaterial::get_anisotropy); + + ObjectTypeDB::bind_method(_MD("set_height_scale","height_scale"),&FixedSpatialMaterial::set_height_scale); + ObjectTypeDB::bind_method(_MD("get_height_scale"),&FixedSpatialMaterial::get_height_scale); + + ObjectTypeDB::bind_method(_MD("set_subsurface_scattering_strength","strength"),&FixedSpatialMaterial::set_subsurface_scattering_strength); + ObjectTypeDB::bind_method(_MD("get_subsurface_scattering_strength"),&FixedSpatialMaterial::get_subsurface_scattering_strength); + + ObjectTypeDB::bind_method(_MD("set_refraction","refraction"),&FixedSpatialMaterial::set_refraction); + ObjectTypeDB::bind_method(_MD("get_refraction"),&FixedSpatialMaterial::get_refraction); + + ObjectTypeDB::bind_method(_MD("set_refraction_roughness","refraction_roughness"),&FixedSpatialMaterial::set_refraction_roughness); + ObjectTypeDB::bind_method(_MD("get_refraction_roughness"),&FixedSpatialMaterial::get_refraction_roughness); + + ObjectTypeDB::bind_method(_MD("set_line_width","line_width"),&FixedSpatialMaterial::set_line_width); + ObjectTypeDB::bind_method(_MD("get_line_width"),&FixedSpatialMaterial::get_line_width); + + ObjectTypeDB::bind_method(_MD("set_point_size","point_size"),&FixedSpatialMaterial::set_point_size); + ObjectTypeDB::bind_method(_MD("get_point_size"),&FixedSpatialMaterial::get_point_size); + + ObjectTypeDB::bind_method(_MD("set_detail_uv","detail_uv"),&FixedSpatialMaterial::set_detail_uv); + ObjectTypeDB::bind_method(_MD("get_detail_uv"),&FixedSpatialMaterial::get_detail_uv); + + ObjectTypeDB::bind_method(_MD("set_blend_mode","blend_mode"),&FixedSpatialMaterial::set_blend_mode); + ObjectTypeDB::bind_method(_MD("get_blend_mode"),&FixedSpatialMaterial::get_blend_mode); + + ObjectTypeDB::bind_method(_MD("set_depth_draw_mode","depth_draw_mode"),&FixedSpatialMaterial::set_depth_draw_mode); + ObjectTypeDB::bind_method(_MD("get_depth_draw_mode"),&FixedSpatialMaterial::get_depth_draw_mode); + + ObjectTypeDB::bind_method(_MD("set_cull_mode","cull_mode"),&FixedSpatialMaterial::set_cull_mode); + ObjectTypeDB::bind_method(_MD("get_cull_mode"),&FixedSpatialMaterial::get_cull_mode); + + ObjectTypeDB::bind_method(_MD("set_diffuse_mode","diffuse_mode"),&FixedSpatialMaterial::set_diffuse_mode); + ObjectTypeDB::bind_method(_MD("get_diffuse_mode"),&FixedSpatialMaterial::get_diffuse_mode); + + ObjectTypeDB::bind_method(_MD("set_flag","flag","enable"),&FixedSpatialMaterial::set_flag); + ObjectTypeDB::bind_method(_MD("get_flag"),&FixedSpatialMaterial::get_flag); + + ObjectTypeDB::bind_method(_MD("set_feature","feature","enable"),&FixedSpatialMaterial::set_feature); + ObjectTypeDB::bind_method(_MD("get_feature","feature"),&FixedSpatialMaterial::get_feature); + + ObjectTypeDB::bind_method(_MD("set_texture","param:Texture","texture"),&FixedSpatialMaterial::set_texture); + ObjectTypeDB::bind_method(_MD("get_texture:Texture","param:Texture"),&FixedSpatialMaterial::get_texture); + + ObjectTypeDB::bind_method(_MD("set_detail_blend_mode","detail_blend_mode"),&FixedSpatialMaterial::set_detail_blend_mode); + ObjectTypeDB::bind_method(_MD("get_detail_blend_mode"),&FixedSpatialMaterial::get_detail_blend_mode); + + ObjectTypeDB::bind_method(_MD("set_uv1_scale","scale"),&FixedSpatialMaterial::set_uv1_scale); + ObjectTypeDB::bind_method(_MD("get_uv1_scale"),&FixedSpatialMaterial::get_uv1_scale); + + ObjectTypeDB::bind_method(_MD("set_uv1_offset","offset"),&FixedSpatialMaterial::set_uv1_offset); + ObjectTypeDB::bind_method(_MD("get_uv1_offset"),&FixedSpatialMaterial::get_uv1_offset); + + ObjectTypeDB::bind_method(_MD("set_uv2_scale","scale"),&FixedSpatialMaterial::set_uv2_scale); + ObjectTypeDB::bind_method(_MD("get_uv2_scale"),&FixedSpatialMaterial::get_uv2_scale); + + ObjectTypeDB::bind_method(_MD("set_uv2_offset","offset"),&FixedSpatialMaterial::set_uv2_offset); + ObjectTypeDB::bind_method(_MD("get_uv2_offset"),&FixedSpatialMaterial::get_uv2_offset); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/transparent"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_TRANSPARENT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/unshaded"),_SCS("set_flag"),_SCS("get_flag"),FLAG_UNSHADED); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/on_top"),_SCS("set_flag"),_SCS("get_flag"),FLAG_ONTOP); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"flags/use_point_size"),_SCS("set_flag"),_SCS("get_flag"),FLAG_USE_POINT_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"vertex_color/use_as_albedo"),_SCS("set_flag"),_SCS("get_flag"),FLAG_ALBEDO_FROM_VERTEX_COLOR); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"vertex_color/is_srgb"),_SCS("set_flag"),_SCS("get_flag"),FLAG_SRGB_VERTEX_COLOR); + + ADD_PROPERTY(PropertyInfo(Variant::INT,"params/diffuse_mode",PROPERTY_HINT_ENUM,"Labert,Lambert Wrap,Oren Nayar,Burley"),_SCS("set_diffuse_mode"),_SCS("get_diffuse_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"params/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,Mul"),_SCS("set_blend_mode"),_SCS("get_blend_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"params/cull_mode",PROPERTY_HINT_ENUM,"Back,Front,Disabled"),_SCS("set_cull_mode"),_SCS("get_cull_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"params/depth_draw_mode",PROPERTY_HINT_ENUM,"Opaque Only,Always,Never,Opaque Pre-Pass"),_SCS("set_depth_draw_mode"),_SCS("get_depth_draw_mode")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"params/line_width",PROPERTY_HINT_RANGE,"0.1,128,0.1"),_SCS("set_line_width"),_SCS("get_line_width")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"params/point_size",PROPERTY_HINT_RANGE,"0.1,128,0.1"),_SCS("set_point_size"),_SCS("get_point_size")); + + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"albedo/color"),_SCS("set_albedo"),_SCS("get_albedo")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"albedo/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_ALBEDO); + + ADD_PROPERTY(PropertyInfo(Variant::INT,"specular/mode",PROPERTY_HINT_ENUM,"Metallic,Specular"),_SCS("set_specular_mode"),_SCS("get_specular_mode")); + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"specular/color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("set_specular"),_SCS("get_specular")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"specular/metalness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_metalness"),_SCS("get_metalness")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"specular/roughness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_roughness"),_SCS("get_roughness")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"specular/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SPECULAR); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"emission/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_EMISSION); + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"emission/color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("set_emission"),_SCS("get_emission")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"emission/energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_emission_energy"),_SCS("get_emission_energy")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"emission/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_EMISSION); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"normal/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_NORMAL_MAPPING); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"normal/scale",PROPERTY_HINT_RANGE,"-16,16,0.01"),_SCS("set_normal_scale"),_SCS("get_normal_scale")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"normal/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_NORMAL); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"rim/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_RIM); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"rim/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_rim"),_SCS("get_rim")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"rim/tint",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_rim_tint"),_SCS("get_rim_tint")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"rim/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_RIM); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"clearcoat/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_CLEARCOAT); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"clearcoat/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_clearcoat"),_SCS("get_clearcoat")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"clearcoat/gloss",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_clearcoat_gloss"),_SCS("get_clearcoat_gloss")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"clearcoat/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_CLEARCOAT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"anisotropy/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_ANISOTROPY); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"anisotropy/anisotropy",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_anisotropy"),_SCS("get_anisotropy")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"anisotropy/flowmap",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_FLOWMAP); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"ao/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_AMBIENT_OCCLUSION); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"ao/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_AMBIENT_OCCLUSION); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"height/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_HEIGHT_MAPPING); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"height/scale",PROPERTY_HINT_RANGE,"-16,16,0.01"),_SCS("set_height_scale"),_SCS("get_height_scale")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"height/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_HEIGHT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"subsurf_scatter/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_SUBSURACE_SCATTERING); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"subsurf_scatter/strength",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_subsurface_scattering_strength"),_SCS("get_subsurface_scattering_strength")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"subsurf_scatter/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SUBSURFACE_SCATTERING); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"refraction/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_REFRACTION); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"refraction/displacement",PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_refraction"),_SCS("get_refraction")); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"refraction/roughness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_refraction_roughness"),_SCS("get_refraction_roughness")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"refraction/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_REFRACTION); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"detail/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_DETAIL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/mask",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_MASK); + ADD_PROPERTY(PropertyInfo(Variant::INT,"detail/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,Mul"),_SCS("set_detail_blend_mode"),_SCS("get_detail_blend_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"detail/uv_layer",PROPERTY_HINT_ENUM,"UV1,UV2"),_SCS("set_detail_uv"),_SCS("get_detail_uv")); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/albedo",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"detail/normal",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_DETAIL_NORMAL); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"uv1/scale"),_SCS("set_uv1_scale"),_SCS("get_uv1_scale")); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"uv1/offset"),_SCS("set_uv1_offset"),_SCS("get_uv1_offset")); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"uv2/scale"),_SCS("set_uv2_scale"),_SCS("get_uv2_scale")); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"uv2/offset"),_SCS("set_uv2_offset"),_SCS("get_uv2_offset")); + + + BIND_CONSTANT( TEXTURE_ALBEDO ); + BIND_CONSTANT( TEXTURE_SPECULAR ); + BIND_CONSTANT( TEXTURE_EMISSION ); + BIND_CONSTANT( TEXTURE_NORMAL ); + BIND_CONSTANT( TEXTURE_RIM ); + BIND_CONSTANT( TEXTURE_CLEARCOAT ); + BIND_CONSTANT( TEXTURE_FLOWMAP ); + BIND_CONSTANT( TEXTURE_AMBIENT_OCCLUSION ); + BIND_CONSTANT( TEXTURE_HEIGHT ); + BIND_CONSTANT( TEXTURE_SUBSURFACE_SCATTERING ); + BIND_CONSTANT( TEXTURE_REFRACTION ); + BIND_CONSTANT( TEXTURE_REFRACTION_ROUGHNESS ); + BIND_CONSTANT( TEXTURE_DETAIL_MASK ); + BIND_CONSTANT( TEXTURE_DETAIL_ALBEDO ); + BIND_CONSTANT( TEXTURE_DETAIL_NORMAL ); + BIND_CONSTANT( TEXTURE_MAX ); + + + BIND_CONSTANT( DETAIL_UV_1 ); + BIND_CONSTANT( DETAIL_UV_2 ); + + BIND_CONSTANT( FEATURE_TRANSPARENT ); + BIND_CONSTANT( FEATURE_EMISSION ); + BIND_CONSTANT( FEATURE_NORMAL_MAPPING ); + BIND_CONSTANT( FEATURE_RIM ); + BIND_CONSTANT( FEATURE_CLEARCOAT ); + BIND_CONSTANT( FEATURE_ANISOTROPY ); + BIND_CONSTANT( FEATURE_AMBIENT_OCCLUSION ); + BIND_CONSTANT( FEATURE_HEIGHT_MAPPING ); + BIND_CONSTANT( FEATURE_SUBSURACE_SCATTERING ); + BIND_CONSTANT( FEATURE_REFRACTION ); + BIND_CONSTANT( FEATURE_DETAIL ); + BIND_CONSTANT( FEATURE_MAX ); + + BIND_CONSTANT( BLEND_MODE_MIX ); + BIND_CONSTANT( BLEND_MODE_ADD ); + BIND_CONSTANT( BLEND_MODE_SUB ); + BIND_CONSTANT( BLEND_MODE_MUL ); + + BIND_CONSTANT( DEPTH_DRAW_OPAQUE_ONLY ); + BIND_CONSTANT( DEPTH_DRAW_ALWAYS ); + BIND_CONSTANT( DEPTH_DRAW_DISABLED ); + BIND_CONSTANT( DEPTH_DRAW_ALPHA_OPAQUE_PREPASS ); + + + BIND_CONSTANT( CULL_BACK ); + BIND_CONSTANT( CULL_FRONT ); + BIND_CONSTANT( CULL_DISABLED ); + + BIND_CONSTANT( FLAG_UNSHADED ); + BIND_CONSTANT( FLAG_ONTOP ); + BIND_CONSTANT( FLAG_ALBEDO_FROM_VERTEX_COLOR ); + BIND_CONSTANT( FLAG_SRGB_VERTEX_COLOR ) + BIND_CONSTANT( FLAG_USE_POINT_SIZE ) + BIND_CONSTANT( FLAG_MAX ); + + BIND_CONSTANT( DIFFUSE_LAMBERT ); + BIND_CONSTANT( DIFFUSE_LAMBERT_WRAP ); + BIND_CONSTANT( DIFFUSE_OREN_NAYAR ); + BIND_CONSTANT( DIFFUSE_BURLEY ); + + BIND_CONSTANT( SPECULAR_MODE_METALLIC ); + BIND_CONSTANT( SPECULAR_MODE_SPECULAR ); - if (shader.is_valid()) { - List<PropertyInfo> pl; - shader->get_param_list(&pl); - for (List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\""); - } - } - } - Material::get_argument_options(p_function,p_idx,r_options); } -ShaderMaterial::ShaderMaterial() :Material(VisualServer::get_singleton()->material_create()){ +FixedSpatialMaterial::FixedSpatialMaterial() : element(this) { + + //initialize to right values + specular_mode=SPECULAR_MODE_METALLIC; + set_albedo(Color(0.7,0.7,0.7,1.0)); + set_specular(Color(0.1,0.1,0.1)); + set_roughness(0.0); + set_metalness(0.1); + set_emission(Color(0,0,0)); + set_emission_energy(1.0); + set_normal_scale(1); + set_rim(1.0); + set_rim_tint(0.5); + set_clearcoat(1); + set_clearcoat_gloss(0.5); + set_anisotropy(0); + set_height_scale(1); + set_subsurface_scattering_strength(0); + set_refraction(0); + set_refraction_roughness(0); + set_line_width(1); + set_point_size(1); + set_uv1_offset(Vector2(0,0)); + set_uv1_scale(Vector2(1,1)); + set_uv2_offset(Vector2(0,0)); + set_uv2_scale(Vector2(1,1)); + + detail_uv=DETAIL_UV_1; + blend_mode=BLEND_MODE_MIX; + detail_blend_mode=BLEND_MODE_MIX; + depth_draw_mode=DEPTH_DRAW_OPAQUE_ONLY; + cull_mode=CULL_BACK; + for(int i=0;i<FLAG_MAX;i++) { + flags[i]=0; + } + diffuse_mode=DIFFUSE_LAMBERT; + + for(int i=0;i<FEATURE_MAX;i++) { + features[i]=false; + } + current_key.key=0; + current_key.invalid_key=1; + _queue_shader_change(); } +FixedSpatialMaterial::~FixedSpatialMaterial() { -///////////////////////////////// + if (material_mutex) + material_mutex->lock(); + + if (shader_map.has(current_key)) { + shader_map[current_key].users--; + if (shader_map[current_key].users==0) { + //deallocate shader, as it's no longer in use + VS::get_singleton()->free(shader_map[current_key].shader); + shader_map.erase(current_key); + } + + VS::get_singleton()->material_set_shader(_get_material(),RID()); + } + + + if (material_mutex) + material_mutex->unlock(); + +} diff --git a/scene/resources/material.h b/scene/resources/material.h index fc1ea3d89a..c2659c4fc4 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -34,7 +34,7 @@ #include "scene/resources/shader.h" #include "resource.h" #include "servers/visual/shader_language.h" - +#include "self_list.h" /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -45,209 +45,367 @@ class Material : public Resource { RES_BASE_EXTENSION("mtl"); OBJ_SAVE_TYPE( Material ); -public: + RID material; +protected: - enum Flag { - FLAG_VISIBLE = VS::MATERIAL_FLAG_VISIBLE, - FLAG_DOUBLE_SIDED = VS::MATERIAL_FLAG_DOUBLE_SIDED, - FLAG_INVERT_FACES = VS::MATERIAL_FLAG_INVERT_FACES, - FLAG_UNSHADED = VS::MATERIAL_FLAG_UNSHADED, - FLAG_ONTOP = VS::MATERIAL_FLAG_ONTOP, - FLAG_LIGHTMAP_ON_UV2 = VS::MATERIAL_FLAG_LIGHTMAP_ON_UV2, - FLAG_COLOR_ARRAY_SRGB = VS::MATERIAL_FLAG_COLOR_ARRAY_SRGB, - FLAG_MAX = VS::MATERIAL_FLAG_MAX - }; + _FORCE_INLINE_ RID _get_material() const { return material; } +public: - enum BlendMode { - BLEND_MODE_MIX = VS::MATERIAL_BLEND_MODE_MIX, - BLEND_MODE_MUL = VS::MATERIAL_BLEND_MODE_MUL, - BLEND_MODE_ADD = VS::MATERIAL_BLEND_MODE_ADD, - BLEND_MODE_SUB = VS::MATERIAL_BLEND_MODE_SUB, - BLEND_MODE_PREMULT_ALPHA = VS::MATERIAL_BLEND_MODE_PREMULT_ALPHA, + virtual RID get_rid() const; + Material(); + virtual ~Material(); +}; - }; - enum DepthDrawMode { - DEPTH_DRAW_ALWAYS = VS::MATERIAL_DEPTH_DRAW_ALWAYS, - DEPTH_DRAW_OPAQUE_ONLY = VS::MATERIAL_DEPTH_DRAW_OPAQUE_ONLY, - DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA = VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA, - DEPTH_DRAW_NEVER = VS::MATERIAL_DEPTH_DRAW_NEVER - }; +class FixedSpatialMaterial : public Material { + OBJ_TYPE(FixedSpatialMaterial,Material) -private: - BlendMode blend_mode; - bool flags[VS::MATERIAL_FLAG_MAX]; - float line_width; - DepthDrawMode depth_draw_mode; -protected: - RID material; +public: - static void _bind_methods(); + enum TextureParam { + TEXTURE_ALBEDO, + TEXTURE_SPECULAR, + TEXTURE_EMISSION, + TEXTURE_NORMAL, + TEXTURE_RIM, + TEXTURE_CLEARCOAT, + TEXTURE_FLOWMAP, + TEXTURE_AMBIENT_OCCLUSION, + TEXTURE_HEIGHT, + TEXTURE_SUBSURFACE_SCATTERING, + TEXTURE_REFRACTION, + TEXTURE_REFRACTION_ROUGHNESS, + TEXTURE_DETAIL_MASK, + TEXTURE_DETAIL_ALBEDO, + TEXTURE_DETAIL_NORMAL, + TEXTURE_MAX -public: - void set_flag(Flag p_flag,bool p_enabled); - bool get_flag(Flag p_flag) const; - void set_blend_mode(BlendMode p_blend_mode); - BlendMode get_blend_mode() const; + }; - void set_depth_draw_mode(DepthDrawMode p_depth_draw_mode); - DepthDrawMode get_depth_draw_mode() const; - void set_line_width(float p_width); - float get_line_width() const; + enum DetailUV { + DETAIL_UV_1, + DETAIL_UV_2 + }; - virtual RID get_rid() const; + enum Feature { + FEATURE_TRANSPARENT, + FEATURE_EMISSION, + FEATURE_NORMAL_MAPPING, + FEATURE_RIM, + FEATURE_CLEARCOAT, + FEATURE_ANISOTROPY, + FEATURE_AMBIENT_OCCLUSION, + FEATURE_HEIGHT_MAPPING, + FEATURE_SUBSURACE_SCATTERING, + FEATURE_REFRACTION, + FEATURE_DETAIL, + FEATURE_MAX + }; - Material(const RID& p_rid=RID()); - virtual ~Material(); -}; -VARIANT_ENUM_CAST( Material::Flag ); -VARIANT_ENUM_CAST( Material::DepthDrawMode ); + enum BlendMode { + BLEND_MODE_MIX, + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MUL, + }; -VARIANT_ENUM_CAST( Material::BlendMode ); + enum DepthDrawMode { + DEPTH_DRAW_OPAQUE_ONLY, + DEPTH_DRAW_ALWAYS, + DEPTH_DRAW_DISABLED, + DEPTH_DRAW_ALPHA_OPAQUE_PREPASS + }; -class FixedMaterial : public Material { + enum CullMode { + CULL_BACK, + CULL_FRONT, + CULL_DISABLED + }; - OBJ_TYPE( FixedMaterial, Material ); - REVERSE_GET_PROPERTY_LIST -public: + enum Flags { + FLAG_UNSHADED, + FLAG_ONTOP, + FLAG_ALBEDO_FROM_VERTEX_COLOR, + FLAG_SRGB_VERTEX_COLOR, + FLAG_USE_POINT_SIZE, + FLAG_MAX + }; - enum Parameter { - PARAM_DIFFUSE=VS::FIXED_MATERIAL_PARAM_DIFFUSE, - PARAM_DETAIL=VS::FIXED_MATERIAL_PARAM_DETAIL, - PARAM_SPECULAR=VS::FIXED_MATERIAL_PARAM_SPECULAR, - PARAM_EMISSION=VS::FIXED_MATERIAL_PARAM_EMISSION, - PARAM_SPECULAR_EXP=VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP, - PARAM_GLOW=VS::FIXED_MATERIAL_PARAM_GLOW, - PARAM_NORMAL=VS::FIXED_MATERIAL_PARAM_NORMAL, - PARAM_SHADE_PARAM=VS::FIXED_MATERIAL_PARAM_SHADE_PARAM, - PARAM_MAX=VS::FIXED_MATERIAL_PARAM_MAX + enum DiffuseMode { + DIFFUSE_LAMBERT, + DIFFUSE_LAMBERT_WRAP, + DIFFUSE_OREN_NAYAR, + DIFFUSE_BURLEY, }; + enum SpecularMode { + SPECULAR_MODE_METALLIC, + SPECULAR_MODE_SPECULAR, + }; - enum TexCoordMode { +private: + union MaterialKey { + + struct { + uint32_t feature_mask : 14; + uint32_t detail_uv : 1; + uint32_t blend_mode : 2; + uint32_t depth_draw_mode : 2; + uint32_t cull_mode : 2; + uint32_t flags : 5; + uint32_t detail_blend_mode : 2; + uint32_t diffuse_mode : 2; + uint32_t invalid_key : 1; + uint32_t specular_mode : 1; + }; + + uint32_t key; + + bool operator<(const MaterialKey& p_key) const { + return key < p_key.key; + } - TEXCOORD_UV=VS::FIXED_MATERIAL_TEXCOORD_UV, - TEXCOORD_UV_TRANSFORM=VS::FIXED_MATERIAL_TEXCOORD_UV_TRANSFORM, - TEXCOORD_UV2=VS::FIXED_MATERIAL_TEXCOORD_UV2, - TEXCOORD_SPHERE=VS::FIXED_MATERIAL_TEXCOORD_SPHERE }; - enum FixedFlag { - FLAG_USE_ALPHA=VS::FIXED_MATERIAL_FLAG_USE_ALPHA, - FLAG_USE_COLOR_ARRAY=VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY, - FLAG_USE_POINT_SIZE=VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE, - FLAG_DISCARD_ALPHA=VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA, - FLAG_USE_XY_NORMALMAP=VS::FIXED_MATERIAL_FLAG_USE_XY_NORMALMAP, - FLAG_MAX=VS::FIXED_MATERIAL_FLAG_MAX + struct ShaderData { + RID shader; + int users; }; - enum LightShader { + static Map<MaterialKey,ShaderData> shader_map; + + MaterialKey current_key; + + _FORCE_INLINE_ MaterialKey _compute_key() const { + + MaterialKey mk; + mk.key=0; + for(int i=0;i<FEATURE_MAX;i++) { + if (features[i]) { + mk.feature_mask|=(1<<i); + } + } + mk.detail_uv=detail_uv; + mk.blend_mode=blend_mode; + mk.depth_draw_mode=depth_draw_mode; + mk.cull_mode=cull_mode; + for(int i=0;i<FLAG_MAX;i++) { + if (flags[i]) { + mk.flags|=(1<<i); + } + } + mk.detail_blend_mode=detail_blend_mode; + mk.diffuse_mode=diffuse_mode; + mk.specular_mode=specular_mode; + + return mk; + } + + struct ShaderNames { + StringName albedo; + StringName specular; + StringName metalness; + StringName roughness; + StringName emission; + StringName emission_energy; + StringName normal_scale; + StringName rim; + StringName rim_tint; + StringName clearcoat; + StringName clearcoat_gloss; + StringName anisotropy; + StringName height_scale; + StringName subsurface_scattering_strength; + StringName refraction; + StringName refraction_roughness; + StringName point_size; + StringName uv1_scale; + StringName uv1_offset; + StringName uv2_scale; + StringName uv2_offset; + StringName texture_names[TEXTURE_MAX]; - LIGHT_SHADER_LAMBERT=VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT, - LIGHT_SHADER_WRAP=VS::FIXED_MATERIAL_LIGHT_SHADER_WRAP, - LIGHT_SHADER_VELVET=VS::FIXED_MATERIAL_LIGHT_SHADER_VELVET, - LIGHT_SHADER_TOON=VS::FIXED_MATERIAL_LIGHT_SHADER_TOON }; -private: + static Mutex *material_mutex; + static SelfList<FixedSpatialMaterial>::List dirty_materials; + static ShaderNames* shader_names; + + SelfList<FixedSpatialMaterial> element; + + void _update_shader(); + _FORCE_INLINE_ void _queue_shader_change(); + _FORCE_INLINE_ bool _is_shader_dirty() const; + + Color albedo; + Color specular; + float metalness; + float roughness; + Color emission; + float emission_energy; + float normal_scale; + float rim; + float rim_tint; + float clearcoat; + float clearcoat_gloss; + float anisotropy; + float height_scale; + float subsurface_scattering_strength; + float refraction; + float refraction_roughness; + float line_width; + float point_size; + Vector2 uv1_scale; + Vector2 uv1_offset; - struct Node { + Vector2 uv2_scale; + Vector2 uv2_offset; - int param; - int mult; - int tex; - }; + DetailUV detail_uv; - Variant param[PARAM_MAX]; - Ref<Texture> texture_param[PARAM_MAX]; - TexCoordMode texture_texcoord[PARAM_MAX]; - LightShader light_shader; - bool fixed_flags[FLAG_MAX]; - float point_size; + BlendMode blend_mode; + BlendMode detail_blend_mode; + DepthDrawMode depth_draw_mode; + CullMode cull_mode; + bool flags[FLAG_MAX]; + DiffuseMode diffuse_mode; + SpecularMode specular_mode; + bool features[FEATURE_MAX]; - Transform uv_transform; + Ref<Texture> textures[TEXTURE_MAX]; -protected: + _FORCE_INLINE_ void _validate_feature(const String& text, Feature feature,PropertyInfo& property) const; +protected: static void _bind_methods(); - + void _validate_property(PropertyInfo& property) const; public: - void set_fixed_flag(FixedFlag p_flag, bool p_value); - bool get_fixed_flag(FixedFlag p_flag) const; - void set_parameter(Parameter p_parameter, const Variant& p_value); - Variant get_parameter(Parameter p_parameter) const; + void set_albedo(const Color& p_albedo); + Color get_albedo() const; - void set_texture(Parameter p_parameter, Ref<Texture> p_texture); - Ref<Texture> get_texture(Parameter p_parameter) const; + void set_specular_mode(SpecularMode p_mode); + SpecularMode get_specular_mode() const; - void set_texcoord_mode(Parameter p_parameter, TexCoordMode p_mode); - TexCoordMode get_texcoord_mode(Parameter p_parameter) const; + void set_specular(const Color& p_specular); + Color get_specular() const; - void set_light_shader(LightShader p_shader); - LightShader get_light_shader() const; + void set_metalness(float p_metalness); + float get_metalness() const; - void set_uv_transform(const Transform& p_transform); - Transform get_uv_transform() const; + void set_roughness(float p_roughness); + float get_roughness() const; - void set_point_size(float p_transform); - float get_point_size() const; + void set_emission(const Color& p_emission); + Color get_emission() const; - FixedMaterial(); - ~FixedMaterial(); + void set_emission_energy(float p_emission_energy); + float get_emission_energy() const; -}; + void set_normal_scale(float p_normal_scale); + float get_normal_scale() const; + void set_rim(float p_rim); + float get_rim() const; + void set_rim_tint(float p_rim_tint); + float get_rim_tint() const; -VARIANT_ENUM_CAST( FixedMaterial::Parameter ); -VARIANT_ENUM_CAST( FixedMaterial::TexCoordMode ); -VARIANT_ENUM_CAST( FixedMaterial::FixedFlag ); -VARIANT_ENUM_CAST( FixedMaterial::LightShader ); + void set_clearcoat(float p_clearcoat); + float get_clearcoat() const; -class ShaderMaterial : public Material { + void set_clearcoat_gloss(float p_clearcoat_gloss); + float get_clearcoat_gloss() const; - OBJ_TYPE( ShaderMaterial, Material ); + void set_anisotropy(float p_anisotropy); + float get_anisotropy() const; - Ref<Shader> shader; + void set_height_scale(float p_height_scale); + float get_height_scale() const; + void set_subsurface_scattering_strength(float p_strength); + float get_subsurface_scattering_strength() const; + void set_refraction(float p_refraction); + float get_refraction() const; - void _shader_changed(); - static void _shader_parse(void*p_self,ShaderLanguage::ProgramNode*p_node); + void set_refraction_roughness(float p_refraction_roughness); + float get_refraction_roughness() const; -protected: + void set_line_width(float p_line_width); + float get_line_width() const; - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List<PropertyInfo> *p_list) const; + void set_point_size(float p_point_size); + float get_point_size() const; - static void _bind_methods(); + void set_detail_uv(DetailUV p_detail_uv); + DetailUV get_detail_uv() const; -public: + void set_blend_mode(BlendMode p_mode); + BlendMode get_blend_mode() const; + + void set_detail_blend_mode(BlendMode p_mode); + BlendMode get_detail_blend_mode() const; + + void set_depth_draw_mode(DepthDrawMode p_mode); + DepthDrawMode get_depth_draw_mode() const; - void set_shader(const Ref<Shader>& p_shader); - Ref<Shader> get_shader() const; + void set_cull_mode(CullMode p_mode); + CullMode get_cull_mode() const; - void set_shader_param(const StringName& p_param,const Variant& p_value); - Variant get_shader_param(const StringName& p_param) const; + void set_diffuse_mode(DiffuseMode p_mode); + DiffuseMode get_diffuse_mode() const; - void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const; + void set_flag(Flags p_flag,bool p_enabled); + bool get_flag(Flags p_flag) const; - ShaderMaterial(); + void set_texture(TextureParam p_param,const Ref<Texture>& p_texture); + Ref<Texture> get_texture(TextureParam p_param) const; + + void set_feature(Feature p_feature,bool p_enabled); + bool get_feature(Feature p_feature) const; + + void set_uv1_scale(const Vector2& p_scale); + Vector2 get_uv1_scale() const; + + void set_uv1_offset(const Vector2& p_offset); + Vector2 get_uv1_offset() const; + + void set_uv2_scale(const Vector2& p_scale); + Vector2 get_uv2_scale() const; + + void set_uv2_offset(const Vector2& p_offset); + Vector2 get_uv2_offset() const; + + static void init_shaders(); + static void finish_shaders(); + static void flush_changes(); + + FixedSpatialMaterial(); + virtual ~FixedSpatialMaterial(); }; +VARIANT_ENUM_CAST( FixedSpatialMaterial::TextureParam ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::DetailUV ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::Feature ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::BlendMode ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::DepthDrawMode ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::CullMode ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::Flags ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::DiffuseMode ) +VARIANT_ENUM_CAST( FixedSpatialMaterial::SpecularMode ) + ////////////////////// diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 4932b5f66f..58c2d08eec 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -122,22 +122,64 @@ bool Mesh::_set(const StringName& p_name, const Variant& p_value) { if (idx==surfaces.size()) { - if (what=="custom") { - add_custom_surface(p_value); - return true; - - } - //create Dictionary d=p_value; ERR_FAIL_COND_V(!d.has("primitive"),false); - ERR_FAIL_COND_V(!d.has("arrays"),false); - ERR_FAIL_COND_V(!d.has("morph_arrays"),false); - bool alphasort = d.has("alphasort") && bool(d["alphasort"]); + if (d.has("arrays")) { + //old format + ERR_FAIL_COND_V(!d.has("morph_arrays"),false); + add_surface_from_arrays(PrimitiveType(int(d["primitive"])),d["arrays"],d["morph_arrays"]); + + } else if (d.has("array_data")) { + + DVector<uint8_t> array_data = d["array_data"]; + DVector<uint8_t> array_index_data; + if (d.has("array_index_data")) + array_index_data=d["array_index_data"]; + + ERR_FAIL_COND_V(!d.has("format"),false); + uint32_t format = d["format"]; + + ERR_FAIL_COND_V(!d.has("primitive"),false); + uint32_t primitive = d["primitive"]; + + ERR_FAIL_COND_V(!d.has("vertex_count"),false); + int vertex_count = d["vertex_count"]; + + int index_count=0; + if (d.has("index_count")) + index_count=d["index_count"]; + + Vector< DVector<uint8_t> > morphs; + + if (d.has("morph_data")) { + Array morph_data=d["morph_data"]; + for(int i=0;i<morph_data.size();i++) { + DVector<uint8_t> morph = morph_data[i]; + morphs.push_back(morph_data[i]); + } + } + + ERR_FAIL_COND_V(!d.has("aabb"),false); + AABB aabb = d["aabb"]; + + Vector<AABB> bone_aabb; + if (d.has("bone_aabb")) { + Array baabb = d["bone_aabb"]; + bone_aabb.resize(baabb.size()); + + for(int i=0;i<baabb.size();i++) { + bone_aabb[i]=baabb[i]; + } + } + + add_surface(format,PrimitiveType(primitive),array_data,vertex_count,array_index_data,index_count,aabb,morphs,bone_aabb); + } else { + ERR_FAIL_V(false); + } - add_surface(PrimitiveType(int(d["primitive"])),d["arrays"],d["morph_arrays"],alphasort); if (d.has("material")) { surface_set_material(idx,d["material"]); @@ -193,10 +235,31 @@ bool Mesh::_get(const StringName& p_name,Variant &r_ret) const { ERR_FAIL_INDEX_V(idx,surfaces.size(),false); Dictionary d; - d["primitive"]=surface_get_primitive_type(idx); - d["arrays"]=surface_get_arrays(idx); - d["morph_arrays"]=surface_get_morph_arrays(idx); - d["alphasort"]=surface_is_alpha_sorting_enabled(idx); + + d["array_data"]=VS::get_singleton()->mesh_surface_get_array(mesh,idx); + d["vertex_count"]=VS::get_singleton()->mesh_surface_get_array_len(mesh,idx); + d["array_index_data"]=VS::get_singleton()->mesh_surface_get_index_array(mesh,idx); + d["index_count"]=VS::get_singleton()->mesh_surface_get_array_index_len(mesh,idx); + d["primitive"]=VS::get_singleton()->mesh_surface_get_primitive_type(mesh,idx); + d["format"]=VS::get_singleton()->mesh_surface_get_format(mesh,idx); + d["aabb"]=VS::get_singleton()->mesh_surface_get_aabb(mesh,idx); + + Vector<AABB> skel_aabb = VS::get_singleton()->mesh_surface_get_skeleton_aabb(mesh,idx); + Array arr; + for(int i=0;i<skel_aabb.size();i++) { + arr[i]=skel_aabb[i]; + } + d["skeleton_aabb"]=arr; + + Vector< DVector<uint8_t> > morph_data = VS::get_singleton()->mesh_surface_get_blend_shapes(mesh,idx); + + Array md; + for(int i=0;i<morph_data.size();i++) { + md.push_back(morph_data[i]); + } + + d["morph_data"]=md; + Ref<Material> m = surface_get_material(idx); if (m.is_valid()) d["material"]=m; @@ -243,14 +306,24 @@ void Mesh::_recompute_aabb() { } -void Mesh::add_surface(PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes,bool p_alphasort) { +void Mesh::add_surface(uint32_t p_format,PrimitiveType p_primitive,const DVector<uint8_t>& p_array,int p_vertex_count,const DVector<uint8_t>& p_index_array,int p_index_count,const AABB& p_aabb,const Vector<DVector<uint8_t> >& p_blend_shapes,const Vector<AABB>& p_bone_aabbs) { + + Surface s; + s.aabb=p_aabb; + surfaces.push_back(s); + + VisualServer::get_singleton()->mesh_add_surface(mesh,p_format,(VS::PrimitiveType)p_primitive,p_array,p_vertex_count,p_index_array,p_index_count,p_aabb,p_blend_shapes,p_bone_aabbs); + +} + +void Mesh::add_surface_from_arrays(PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes,uint32_t p_flags) { ERR_FAIL_COND(p_arrays.size()!=ARRAY_MAX); Surface s; - VisualServer::get_singleton()->mesh_add_surface(mesh,(VisualServer::PrimitiveType)p_primitive, p_arrays,p_blend_shapes,p_alphasort); + VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh,(VisualServer::PrimitiveType)p_primitive, p_arrays,p_blend_shapes,p_flags); surfaces.push_back(s); @@ -274,7 +347,6 @@ void Mesh::add_surface(PrimitiveType p_primitive,const Array& p_arrays,const Arr } surfaces[surfaces.size()-1].aabb=aabb; - surfaces[surfaces.size()-1].alphasort=p_alphasort; _recompute_aabb(); @@ -289,29 +361,18 @@ void Mesh::add_surface(PrimitiveType p_primitive,const Array& p_arrays,const Arr Array Mesh::surface_get_arrays(int p_surface) const { ERR_FAIL_INDEX_V(p_surface,surfaces.size(),Array()); - return VisualServer::get_singleton()->mesh_get_surface_arrays(mesh,p_surface); + return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh,p_surface); } Array Mesh::surface_get_morph_arrays(int p_surface) const { ERR_FAIL_INDEX_V(p_surface,surfaces.size(),Array()); - return VisualServer::get_singleton()->mesh_get_surface_morph_arrays(mesh,p_surface); + return Array(); } -void Mesh::add_custom_surface(const Variant& p_data) { - - Surface s; - s.aabb=AABB(); - VisualServer::get_singleton()->mesh_add_custom_surface(mesh,p_data); - surfaces.push_back(s); - - triangle_mesh=Ref<TriangleMesh>(); - _change_notify(); -} - int Mesh::get_surface_count() const { @@ -418,11 +479,6 @@ Mesh::PrimitiveType Mesh::surface_get_primitive_type(int p_idx) const { return (PrimitiveType)VisualServer::get_singleton()->mesh_surface_get_primitive_type( mesh, p_idx ); } -bool Mesh::surface_is_alpha_sorting_enabled(int p_idx) const { - - ERR_FAIL_INDEX_V( p_idx, surfaces.size(), 0 ); - return surfaces[p_idx].alphasort; -} void Mesh::surface_set_material(int p_idx, const Ref<Material>& p_material) { @@ -719,8 +775,10 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { DVector<int> indices = a[ARRAY_INDEX]; DVector<int>::Read ir = indices.read(); - for(int i=0;i<ic;i++) - facesw[widx++]=vr[ ir[i] ]; + for(int i=0;i<ic;i++) { + int index = ir[i]; + facesw[widx++]=vr[ index ]; + } } else { @@ -954,7 +1012,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { Ref<Mesh> newmesh = memnew( Mesh ); - newmesh->add_surface(PRIMITIVE_TRIANGLES,arrays); + newmesh->add_surface_from_arrays(PRIMITIVE_TRIANGLES,arrays); return newmesh; } @@ -968,7 +1026,7 @@ void Mesh::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_morph_target_mode","mode"),&Mesh::set_morph_target_mode); ObjectTypeDB::bind_method(_MD("get_morph_target_mode"),&Mesh::get_morph_target_mode); - ObjectTypeDB::bind_method(_MD("add_surface","primitive","arrays","morph_arrays","alphasort"),&Mesh::add_surface,DEFVAL(Array()),DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("add_surface_from_arrays","primitive","arrays","blend_shapes","compress_flags"),&Mesh::add_surface_from_arrays,DEFVAL(Array()),DEFVAL(ARRAY_COMPRESS_DEFAULT)); ObjectTypeDB::bind_method(_MD("get_surface_count"),&Mesh::get_surface_count); ObjectTypeDB::bind_method(_MD("surface_remove","surf_idx"),&Mesh::surface_remove); ObjectTypeDB::bind_method(_MD("surface_get_array_len","surf_idx"),&Mesh::surface_get_array_len); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 61731b163e..399cd8921f 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -77,6 +77,22 @@ public: ARRAY_FORMAT_WEIGHTS=1<<ARRAY_WEIGHTS, ARRAY_FORMAT_INDEX=1<<ARRAY_INDEX, + ARRAY_COMPRESS_BASE=(ARRAY_INDEX+1), + ARRAY_COMPRESS_VERTEX=1<<(ARRAY_VERTEX+ARRAY_COMPRESS_BASE), // mandatory + ARRAY_COMPRESS_NORMAL=1<<(ARRAY_NORMAL+ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_TANGENT=1<<(ARRAY_TANGENT+ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_COLOR=1<<(ARRAY_COLOR+ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_TEX_UV=1<<(ARRAY_TEX_UV+ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_TEX_UV2=1<<(ARRAY_TEX_UV2+ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_BONES=1<<(ARRAY_BONES+ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_WEIGHTS=1<<(ARRAY_WEIGHTS+ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_INDEX=1<<(ARRAY_INDEX+ARRAY_COMPRESS_BASE), + + ARRAY_FLAG_USE_2D_VERTICES=ARRAY_COMPRESS_INDEX<<1, + ARRAY_FLAG_USE_16_BIT_BONES=ARRAY_COMPRESS_INDEX<<2, + + ARRAY_COMPRESS_DEFAULT=ARRAY_COMPRESS_VERTEX|ARRAY_COMPRESS_NORMAL|ARRAY_COMPRESS_TANGENT|ARRAY_COMPRESS_COLOR|ARRAY_COMPRESS_TEX_UV|ARRAY_COMPRESS_TEX_UV2|ARRAY_COMPRESS_WEIGHTS + }; enum PrimitiveType { @@ -99,7 +115,6 @@ private: struct Surface { String name; AABB aabb; - bool alphasort; Ref<Material> material; }; Vector<Surface> surfaces; @@ -123,12 +138,12 @@ protected: public: - void add_surface(PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes=Array(),bool p_alphasort=false); + void add_surface_from_arrays(PrimitiveType p_primitive, const Array& p_arrays, const Array& p_blend_shapes=Array(), uint32_t p_flags=ARRAY_COMPRESS_DEFAULT); + void add_surface(uint32_t p_format,PrimitiveType p_primitive,const DVector<uint8_t>& p_array,int p_vertex_count,const DVector<uint8_t>& p_index_array,int p_index_count,const AABB& p_aabb,const Vector<DVector<uint8_t> >& p_blend_shapes=Vector<DVector<uint8_t> >(),const Vector<AABB>& p_bone_aabbs=Vector<AABB>()); + Array surface_get_arrays(int p_surface) const; virtual Array surface_get_morph_arrays(int p_surface) const; - void add_custom_surface(const Variant& p_data); //only recognized by driver - void add_morph_target(const StringName& p_name); int get_morph_target_count() const; StringName get_morph_target_name(int p_index) const; diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index df36390c0e..e06ff6fd52 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -328,7 +328,7 @@ Error MeshDataTool::commit_to_surface(const Ref<Mesh>& p_mesh) { Ref<Mesh> ncmesh=p_mesh; int sc = ncmesh->get_surface_count(); - ncmesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,arr); + ncmesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES,arr); ncmesh->surface_set_material(sc,material); return OK; diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index 2554b17a98..b96ad155c0 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -141,7 +141,7 @@ Ref<Mesh> MultiMesh::get_mesh() const { void MultiMesh::set_instance_count(int p_count) { - VisualServer::get_singleton()->multimesh_set_instance_count(multimesh,p_count); + VisualServer::get_singleton()->multimesh_allocate(multimesh,p_count,VS::MultimeshTransformFormat(transform_format),VS::MultimeshColorFormat(color_format)); } int MultiMesh::get_instance_count() const { @@ -174,66 +174,58 @@ Color MultiMesh::get_instance_color(int p_instance) const { } -void MultiMesh::set_aabb(const AABB& p_aabb) { - aabb=p_aabb; - VisualServer::get_singleton()->multimesh_set_aabb(multimesh,p_aabb); - - -} AABB MultiMesh::get_aabb() const { - return aabb; + return VisualServer::get_singleton()->multimesh_get_aabb(multimesh); } -void MultiMesh::generate_aabb() { - - - - ERR_EXPLAIN("Cannot generate AABB if mesh is null."); - ERR_FAIL_COND(mesh.is_null()); - AABB base_aabb=mesh->get_aabb(); +RID MultiMesh::get_rid() const { - aabb=AABB(); + return multimesh; - int instance_count = get_instance_count(); - for(int i=0;i<instance_count;i++) { +} - Transform xform = get_instance_transform(i); - if(i==0) - aabb=xform.xform(base_aabb); - else - aabb.merge_with(xform.xform(base_aabb)); +void MultiMesh::set_color_format(ColorFormat p_color_format) { - } + color_format=p_color_format; +} - set_aabb(aabb); +MultiMesh::ColorFormat MultiMesh::get_color_format() const{ + return color_format; } -RID MultiMesh::get_rid() const { +void MultiMesh::set_transform_format(TransformFormat p_transform_format){ - return multimesh; + transform_format=p_transform_format; +} +MultiMesh::TransformFormat MultiMesh::get_transform_format() const{ + return transform_format; } + void MultiMesh::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_mesh","mesh:Mesh"),&MultiMesh::set_mesh); ObjectTypeDB::bind_method(_MD("get_mesh:Mesh"),&MultiMesh::get_mesh); + ObjectTypeDB::bind_method(_MD("set_color_format","format"),&MultiMesh::set_color_format); + ObjectTypeDB::bind_method(_MD("get_color_format"),&MultiMesh::get_color_format); + ObjectTypeDB::bind_method(_MD("set_transform_format","format"),&MultiMesh::set_transform_format); + ObjectTypeDB::bind_method(_MD("get_transform_format"),&MultiMesh::get_transform_format); + ObjectTypeDB::bind_method(_MD("set_instance_count","count"),&MultiMesh::set_instance_count); ObjectTypeDB::bind_method(_MD("get_instance_count"),&MultiMesh::get_instance_count); ObjectTypeDB::bind_method(_MD("set_instance_transform","instance","transform"),&MultiMesh::set_instance_transform); ObjectTypeDB::bind_method(_MD("get_instance_transform","instance"),&MultiMesh::get_instance_transform); ObjectTypeDB::bind_method(_MD("set_instance_color","instance","color"),&MultiMesh::set_instance_color); ObjectTypeDB::bind_method(_MD("get_instance_color","instance"),&MultiMesh::get_instance_color); - ObjectTypeDB::bind_method(_MD("set_aabb","visibility_aabb"),&MultiMesh::set_aabb); ObjectTypeDB::bind_method(_MD("get_aabb"),&MultiMesh::get_aabb); - ObjectTypeDB::bind_method(_MD("generate_aabb"),&MultiMesh::generate_aabb); ObjectTypeDB::bind_method(_MD("_set_transform_array"),&MultiMesh::_set_transform_array); ObjectTypeDB::bind_method(_MD("_get_transform_array"),&MultiMesh::_get_transform_array); @@ -241,17 +233,28 @@ void MultiMesh::_bind_methods() { ObjectTypeDB::bind_method(_MD("_get_color_array"),&MultiMesh::_get_color_array); + ADD_PROPERTY(PropertyInfo(Variant::INT,"color_format",PROPERTY_HINT_ENUM,"None,Byte,Float"), _SCS("set_color_format"), _SCS("get_color_format")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"transform_format",PROPERTY_HINT_ENUM,"2D,3D"), _SCS("set_transform_format"), _SCS("get_transform_format")); ADD_PROPERTY(PropertyInfo(Variant::INT,"instance_count",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_instance_count"), _SCS("get_instance_count")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"mesh",PROPERTY_HINT_RESOURCE_TYPE,"Mesh"), _SCS("set_mesh"), _SCS("get_mesh")); - ADD_PROPERTY(PropertyInfo(Variant::_AABB,"aabb"), _SCS("set_aabb"), _SCS("get_aabb") ); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3_ARRAY,"transform_array",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR), _SCS("_set_transform_array"), _SCS("_get_transform_array")); ADD_PROPERTY(PropertyInfo(Variant::COLOR_ARRAY,"color_array",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR), _SCS("_set_color_array"), _SCS("_get_color_array")); + + + BIND_CONSTANT( TRANSFORM_2D ); + BIND_CONSTANT( TRANSFORM_3D ); + BIND_CONSTANT( COLOR_NONE ); + BIND_CONSTANT( COLOR_8BIT ); + BIND_CONSTANT( COLOR_FLOAT ); + } MultiMesh::MultiMesh() { multimesh = VisualServer::get_singleton()->multimesh_create(); + color_format=COLOR_NONE; + transform_format=TRANSFORM_2D; } MultiMesh::~MultiMesh() { diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 448b4b3413..85c8718aa7 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -30,16 +30,31 @@ #define MULTIMESH_H #include "scene/resources/mesh.h" - +#include "servers/visual_server.h" class MultiMesh : public Resource { OBJ_TYPE( MultiMesh, Resource ); RES_BASE_EXTENSION("mmsh"); +public: - AABB aabb; + enum TransformFormat { + TRANSFORM_2D = VS::MULTIMESH_TRANSFORM_2D, + TRANSFORM_3D = VS::MULTIMESH_TRANSFORM_3D + }; + + enum ColorFormat { + COLOR_NONE = VS::MULTIMESH_COLOR_NONE, + COLOR_8BIT = VS::MULTIMESH_COLOR_8BIT, + COLOR_FLOAT = VS::MULTIMESH_COLOR_FLOAT, + }; +private: Ref<Mesh> mesh; RID multimesh; + TransformFormat transform_format; + ColorFormat color_format; + + protected: static void _bind_methods(); @@ -55,6 +70,12 @@ public: void set_mesh(const Ref<Mesh>& p_mesh); Ref<Mesh> get_mesh() const; + void set_color_format(ColorFormat p_color_format); + ColorFormat get_color_format() const; + + void set_transform_format(TransformFormat p_transform_format); + TransformFormat get_transform_format() const; + void set_instance_count(int p_count); int get_instance_count() const; @@ -64,11 +85,8 @@ public: void set_instance_color(int p_instance, const Color& p_color); Color get_instance_color(int p_instance) const; - void set_aabb(const AABB& p_aabb); virtual AABB get_aabb() const; - void generate_aabb(); - virtual RID get_rid() const; MultiMesh(); @@ -76,4 +94,8 @@ public: }; + +VARIANT_ENUM_CAST( MultiMesh::TransformFormat ); +VARIANT_ENUM_CAST( MultiMesh::ColorFormat); + #endif // MULTI_MESH_H diff --git a/scene/resources/room.cpp b/scene/resources/room.cpp index dee2ea8ea2..dd833a3f2a 100644 --- a/scene/resources/room.cpp +++ b/scene/resources/room.cpp @@ -36,16 +36,6 @@ RID RoomBounds::get_rid() const { return area; } -void RoomBounds::set_bounds( const BSP_Tree& p_bounds ) { - - VisualServer::get_singleton()->room_set_bounds(area,p_bounds); - emit_signal("changed"); -} - -BSP_Tree RoomBounds::get_bounds() const { - - return VisualServer::get_singleton()->room_get_bounds(area); -} void RoomBounds::set_geometry_hint(const DVector<Face3>& p_geometry_hint) { @@ -57,41 +47,15 @@ DVector<Face3> RoomBounds::get_geometry_hint() const { return geometry_hint; } -void RoomBounds::_regenerate_bsp_cubic() { - - if (geometry_hint.size()) { - - float err=0; - geometry_hint= Geometry::wrap_geometry( geometry_hint, &err ); ///< create a "wrap" that encloses the given geometry - BSP_Tree new_bounds(geometry_hint,err); - set_bounds(new_bounds); - } - -} - -void RoomBounds::_regenerate_bsp() { - - if (geometry_hint.size()) { - - BSP_Tree new_bounds(geometry_hint,0); - set_bounds(new_bounds); - } -} void RoomBounds::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_bounds","bsp_tree"),&RoomBounds::set_bounds); - ObjectTypeDB::bind_method(_MD("get_bounds"),&RoomBounds::get_bounds); ObjectTypeDB::bind_method(_MD("set_geometry_hint","triangles"),&RoomBounds::set_geometry_hint); ObjectTypeDB::bind_method(_MD("get_geometry_hint"),&RoomBounds::get_geometry_hint); - ObjectTypeDB::bind_method(_MD("regenerate_bsp"),&RoomBounds::_regenerate_bsp); - ObjectTypeDB::set_method_flags(get_type_static(),_SCS("regenerate_bsp"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); - ObjectTypeDB::bind_method(_MD("regenerate_bsp_cubic"),&RoomBounds::_regenerate_bsp_cubic); - ObjectTypeDB::set_method_flags(get_type_static(),_SCS("regenerate_bsp_cubic"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); - ADD_PROPERTY( PropertyInfo( Variant::DICTIONARY, "bounds"), _SCS("set_bounds"),_SCS("get_bounds") ); + //ADD_PROPERTY( PropertyInfo( Variant::DICTIONARY, "bounds"), _SCS("set_bounds"),_SCS("get_bounds") ); ADD_PROPERTY( PropertyInfo( Variant::VECTOR3_ARRAY, "geometry_hint"),_SCS("set_geometry_hint"),_SCS("get_geometry_hint") ); } diff --git a/scene/resources/room.h b/scene/resources/room.h index 5b0950ce34..6ecd7e846d 100644 --- a/scene/resources/room.h +++ b/scene/resources/room.h @@ -34,6 +34,7 @@ /** @author Juan Linietsky <reduzio@gmail.com> */ + class RoomBounds : public Resource { OBJ_TYPE( RoomBounds, Resource ); @@ -42,8 +43,7 @@ class RoomBounds : public Resource { RID area; DVector<Face3> geometry_hint; - void _regenerate_bsp(); - void _regenerate_bsp_cubic(); + protected: static void _bind_methods(); @@ -52,8 +52,6 @@ public: virtual RID get_rid() const; - void set_bounds( const BSP_Tree& p_bounds ); - BSP_Tree get_bounds() const; void set_geometry_hint(const DVector<Face3>& geometry_hint); DVector<Face3> get_geometry_hint() const; @@ -63,4 +61,6 @@ public: }; + + #endif // ROOM_H diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 8000941157..3ce1a00af4 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -39,37 +39,17 @@ Shader::Mode Shader::get_mode() const { return mode; } -void Shader::set_code( const String& p_vertex, const String& p_fragment, const String& p_light,int p_fragment_ofs,int p_light_ofs) { +void Shader::set_code(const String& p_code) { - VisualServer::get_singleton()->shader_set_code(shader,p_vertex,p_fragment,p_light,0,p_fragment_ofs,p_light_ofs); + VisualServer::get_singleton()->shader_set_code(shader,p_code); params_cache_dirty=true; emit_signal(SceneStringNames::get_singleton()->changed); } -String Shader::get_vertex_code() const { +String Shader::get_code() const { - return VisualServer::get_singleton()->shader_get_vertex_code(shader); -} - -String Shader::get_fragment_code() const { - - return VisualServer::get_singleton()->shader_get_fragment_code(shader); - -} - -String Shader::get_light_code() const { - - return VisualServer::get_singleton()->shader_get_light_code(shader); - -} - -bool Shader::has_param(const StringName& p_param) const { - - if (params_cache_dirty) - get_param_list(NULL); - - return (params_cache.has(p_param)); + return VisualServer::get_singleton()->shader_get_code(shader); } @@ -101,48 +81,6 @@ RID Shader::get_rid() const { return shader; } -Dictionary Shader::_get_code() { - - String fs = VisualServer::get_singleton()->shader_get_fragment_code(shader); - String vs = VisualServer::get_singleton()->shader_get_vertex_code(shader); - String ls = VisualServer::get_singleton()->shader_get_light_code(shader); - - Dictionary c; - c["fragment"]=fs; - c["fragment_ofs"]=0; - c["vertex"]=vs; - c["vertex_ofs"]=0; - c["light"]=ls; - c["light_ofs"]=0; - Array arr; - for(const Map<StringName,Ref<Texture> >::Element *E=default_textures.front();E;E=E->next()) { - arr.push_back(E->key()); - arr.push_back(E->get()); - } - if (arr.size()) - c["default_tex"]=arr; - return c; -} - -void Shader::_set_code(const Dictionary& p_string) { - - ERR_FAIL_COND(!p_string.has("fragment")); - ERR_FAIL_COND(!p_string.has("vertex")); - String light; - if (p_string.has("light")) - light=p_string["light"]; - - set_code(p_string["vertex"],p_string["fragment"],light); - if (p_string.has("default_tex")) { - Array arr=p_string["default_tex"]; - if ((arr.size()&1)==0) { - for(int i=0;i<arr.size();i+=2) { - - set_default_texture_param(arr[i],arr[i+1]); - } - } - } -} void Shader::set_default_texture_param(const StringName& p_param,const Ref<Texture>& p_texture) { @@ -171,33 +109,31 @@ void Shader::get_default_texture_param_list(List<StringName>* r_textures) const{ } } +bool Shader::has_param(const StringName& p_param) const { + return params_cache.has(p_param); +} void Shader::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_mode"),&Shader::get_mode); - ObjectTypeDB::bind_method(_MD("set_code","vcode","fcode","lcode","fofs","lofs"),&Shader::set_code,DEFVAL(0),DEFVAL(0)); - ObjectTypeDB::bind_method(_MD("get_vertex_code"),&Shader::get_vertex_code); - ObjectTypeDB::bind_method(_MD("get_fragment_code"),&Shader::get_fragment_code); - ObjectTypeDB::bind_method(_MD("get_light_code"),&Shader::get_light_code); + ObjectTypeDB::bind_method(_MD("set_code","code"),&Shader::set_code); + ObjectTypeDB::bind_method(_MD("get_code"),&Shader::get_code); ObjectTypeDB::bind_method(_MD("set_default_texture_param","param","texture:Texture"),&Shader::set_default_texture_param); ObjectTypeDB::bind_method(_MD("get_default_texture_param:Texture","param"),&Shader::get_default_texture_param); ObjectTypeDB::bind_method(_MD("has_param","name"),&Shader::has_param); - ObjectTypeDB::bind_method(_MD("_set_code","code"),&Shader::_set_code); - ObjectTypeDB::bind_method(_MD("_get_code"),&Shader::_get_code); - //ObjectTypeDB::bind_method(_MD("get_param_list"),&Shader::get_fragment_code); - ADD_PROPERTY( PropertyInfo(Variant::STRING, "_code",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR), _SCS("_set_code"), _SCS("_get_code") ); + ADD_PROPERTY( PropertyInfo(Variant::STRING, "code",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR), _SCS("set_code"), _SCS("get_code") ); - BIND_CONSTANT( MODE_MATERIAL ); + BIND_CONSTANT( MODE_SPATIAL); BIND_CONSTANT( MODE_CANVAS_ITEM ); - BIND_CONSTANT( MODE_POST_PROCESS ); + BIND_CONSTANT( MODE_PARTICLES ); } @@ -214,253 +150,3 @@ Shader::~Shader() { } - -/************ Loader from text ***************/ - - - -RES ResourceFormatLoaderShader::load(const String &p_path, const String& p_original_path, Error *r_error) { - - if (r_error) - *r_error=ERR_FILE_CANT_OPEN; - - String fragment_code; - String vertex_code; - String light_code; - - int mode=-1; - - Error err; - FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err); - - - ERR_EXPLAIN("Unable to open shader file: "+p_path); - ERR_FAIL_COND_V(err,RES()); - String base_path = p_path.get_base_dir(); - - if (r_error) - *r_error=ERR_FILE_CORRUPT; - - Ref<Shader> shader;//( memnew( Shader ) ); - - int line=0; - - while(!f->eof_reached()) { - - String l = f->get_line(); - line++; - - if (mode<=0) { - l = l.strip_edges(); - int comment = l.find(";"); - if (comment!=-1) - l=l.substr(0,comment); - } - - if (mode<1) - vertex_code+="\n"; - if (mode<2) - fragment_code+="\n"; - - if (mode < 1 && l=="") - continue; - - if (l.begins_with("[")) { - l=l.strip_edges(); - if (l=="[params]") { - if (mode>=0) { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Misplaced [params] section."); - ERR_FAIL_V(RES()); - } - mode=0; - } else if (l=="[vertex]") { - if (mode>=1) { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Misplaced [vertex] section."); - ERR_FAIL_V(RES()); - } - mode=1; - } else if (l=="[fragment]") { - if (mode>=2) { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Misplaced [fragment] section."); - ERR_FAIL_V(RES()); - } - mode=1; - } else { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Unknown section type: '"+l+"'."); - ERR_FAIL_V(RES()); - } - continue; - } - - if (mode==0) { - - int eqpos = l.find("="); - if (eqpos==-1) { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Expected '='."); - ERR_FAIL_V(RES()); - } - - - String right=l.substr(eqpos+1,l.length()).strip_edges(); - if (right=="") { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Expected value after '='."); - ERR_FAIL_V(RES()); - } - - Variant value; - - if (right=="true") { - value = true; - } else if (right=="false") { - value = false; - } else if (right.is_valid_float()) { - //is number - value = right.to_double(); - } else if (right.is_valid_html_color()) { - //is html color - value = Color::html(right); - } else { - //attempt to parse a constructor - int popenpos = right.find("("); - - if (popenpos==-1) { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor syntax: "+right); - ERR_FAIL_V(RES()); - } - - int pclosepos = right.find_last(")"); - - if (pclosepos==-1) { - ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor parameter syntax: "+right); - ERR_FAIL_V(RES()); - - } - - String type = right.substr(0,popenpos); - String param = right.substr(popenpos+1,pclosepos-popenpos-1).strip_edges(); - - - if (type=="tex") { - - if (param=="") { - - value=RID(); - } else { - - String path; - - if (param.is_abs_path()) - path=param; - else - path=base_path+"/"+param; - - Ref<Texture> texture = ResourceLoader::load(path); - if (!texture.is_valid()) { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Couldn't find icon at path: "+path); - ERR_FAIL_V(RES()); - } - - value=texture; - } - - } else if (type=="vec3") { - - if (param=="") { - value=Vector3(); - } else { - Vector<String> params = param.split(","); - if (params.size()!=3) { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid param count for vec3(): '"+right+"'."); - ERR_FAIL_V(RES()); - - } - - Vector3 v; - for(int i=0;i<3;i++) - v[i]=params[i].to_double(); - value=v; - } - - - } else if (type=="xform") { - - if (param=="") { - value=Transform(); - } else { - - Vector<String> params = param.split(","); - if (params.size()!=12) { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid param count for xform(): '"+right+"'."); - ERR_FAIL_V(RES()); - - } - - Transform t; - for(int i=0;i<9;i++) - t.basis[i%3][i/3]=params[i].to_double(); - for(int i=0;i<3;i++) - t.origin[i]=params[i-9].to_double(); - - value=t; - } - - } else { - memdelete(f); - ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor type: '"+type+"'."); - ERR_FAIL_V(RES()); - - } - - } - - String left= l.substr(0,eqpos); - -// shader->set_param(left,value); - } else if (mode==1) { - - vertex_code+=l; - - } else if (mode==2) { - - fragment_code+=l; - } - } - - shader->set_code(vertex_code,fragment_code,light_code); - - f->close(); - memdelete(f); - if (r_error) - *r_error=OK; - - return shader; -} - -void ResourceFormatLoaderShader::get_recognized_extensions(List<String> *p_extensions) const { - - ObjectTypeDB::get_extensions_for_type("Shader", p_extensions); -} - -bool ResourceFormatLoaderShader::handles_type(const String& p_type) const { - - return ObjectTypeDB::is_type(p_type, "Shader"); -} - - -String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const { - - if (p_path.extension().to_lower()=="shd") - return "Shader"; - return ""; -} - diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 94ee04812a..279cf5b7c9 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -32,6 +32,7 @@ #include "resource.h" #include "io/resource_loader.h" #include "scene/resources/texture.h" + class Shader : public Resource { OBJ_TYPE(Shader,Resource); @@ -41,17 +42,14 @@ class Shader : public Resource { public: enum Mode { - MODE_MATERIAL, + MODE_SPATIAL, MODE_CANVAS_ITEM, - MODE_POST_PROCESS, + MODE_PARTICLES, MODE_MAX }; private: RID shader; Mode mode; - Dictionary _get_code(); - void _set_code(const Dictionary& p_string); - // hack the name of performance // shaders keep a list of ShaderMaterial -> VisualServer name translations, to make @@ -73,10 +71,8 @@ public: //void set_mode(Mode p_mode); Mode get_mode() const; - void set_code( const String& p_vertex, const String& p_fragment, const String& p_light,int p_fragment_ofs=0,int p_light_ofs=0); - String get_vertex_code() const; - String get_fragment_code() const; - String get_light_code() const; + void set_code( const String& p_code); + String get_code() const; void get_param_list(List<PropertyInfo> *p_params) const; bool has_param(const StringName& p_param) const; @@ -104,13 +100,13 @@ public: VARIANT_ENUM_CAST( Shader::Mode ); -class MaterialShader : public Shader { +class SpatialShader : public Shader { - OBJ_TYPE(MaterialShader,Shader); + OBJ_TYPE(SpatialShader,Shader); public: - MaterialShader() : Shader(MODE_MATERIAL) {}; + SpatialShader() : Shader(MODE_SPATIAL) {}; }; class CanvasItemShader : public Shader { @@ -123,15 +119,14 @@ public: }; +class ParticlesShader : public Shader { + + OBJ_TYPE(ParticlesShader,Shader); -class ResourceFormatLoaderShader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - virtual bool handles_type(const String& p_type) const; - virtual String get_resource_type(const String &p_path) const; -}; + ParticlesShader() : Shader(MODE_PARTICLES) {}; +}; #endif // SHADER_H diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index e019b455c0..f56aa8dbc1 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -29,6 +29,7 @@ #include "shader_graph.h" #include "scene/scene_string_names.h" +#if 0 Array ShaderGraph::_get_node_list(ShaderType p_type) const { List<int> nodes; @@ -2489,7 +2490,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str } } - Image gradient(color_ramp_len,1,0,Image::FORMAT_RGBA,cramp); + Image gradient(color_ramp_len,1,0,Image::FORMAT_RGBA8,cramp); Ref<ImageTexture> it = memnew( ImageTexture ); it->create_from_image(gradient,Texture::FLAG_FILTER|Texture::FLAG_MIPMAPS); @@ -2559,7 +2560,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str - Image gradient(curve_map_len,1,0,Image::FORMAT_GRAYSCALE,cmap); + Image gradient(curve_map_len,1,0,Image::FORMAT_L8,cmap); Ref<ImageTexture> it = memnew( ImageTexture ); it->create_from_image(gradient,Texture::FLAG_FILTER|Texture::FLAG_MIPMAPS); @@ -2660,3 +2661,5 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str #undef DEF_MATRIX #undef DEF_VEC } + +#endif diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index 2dfe6b66d4..c8d0d3d715 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -30,7 +30,7 @@ #define SHADER_GRAPH_H - +#if 0 #include "map.h" #include "scene/resources/shader.h" @@ -440,5 +440,5 @@ public: } }; - +#endif #endif // SHADER_GRAPH_H diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp index 3e91fd0ead..f00443276f 100644 --- a/scene/resources/shape.cpp +++ b/scene/resources/shape.cpp @@ -77,7 +77,7 @@ Ref<Mesh> Shape::get_debug_mesh() { SceneTree *st=OS::get_singleton()->get_main_loop()->cast_to<SceneTree>(); - debug_mesh_cache->add_surface(Mesh::PRIMITIVE_LINES,arr); + debug_mesh_cache->add_surface_from_arrays(Mesh::PRIMITIVE_LINES,arr); if (st) { debug_mesh_cache->surface_set_material(0,st->get_debug_collision_material()); diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp new file mode 100644 index 0000000000..e8017cb084 --- /dev/null +++ b/scene/resources/sky_box.cpp @@ -0,0 +1,158 @@ +#include "sky_box.h" +#include "io/image_loader.h" + + +void SkyBox::set_radiance_size(RadianceSize p_size) { + ERR_FAIL_INDEX(p_size,RADIANCE_SIZE_MAX); + + radiance_size=p_size; + _radiance_changed(); +} + +SkyBox::RadianceSize SkyBox::get_radiance_size() const { + + return radiance_size; +} + +void SkyBox::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_radiance_size","size"),&SkyBox::set_radiance_size); + ObjectTypeDB::bind_method(_MD("get_radiance_size"),&SkyBox::get_radiance_size); + + ADD_PROPERTY(PropertyInfo(Variant::INT,"radiance_size",PROPERTY_HINT_ENUM,"256,512,1024,2048"),_SCS("set_radiance_size"),_SCS("get_radiance_size")); + + + BIND_CONSTANT( RADIANCE_SIZE_256 ); + BIND_CONSTANT( RADIANCE_SIZE_512 ); + BIND_CONSTANT( RADIANCE_SIZE_1024 ); + BIND_CONSTANT( RADIANCE_SIZE_2048 ); + BIND_CONSTANT( RADIANCE_SIZE_MAX ); +} + +SkyBox::SkyBox() +{ + radiance_size=RADIANCE_SIZE_512; +} + +///////////////////////////////////////// + + + +void ImageSkyBox::_radiance_changed() { + + if (cube_map_valid) { + static const int size[RADIANCE_SIZE_MAX]={ + 256,512,1024,2048 + }; + VS::get_singleton()->skybox_set_texture(sky_box,cube_map,size[get_radiance_size()]); + } +} + +void ImageSkyBox::set_image_path(ImagePath p_image,const String &p_path) { + + ERR_FAIL_INDEX(p_image,IMAGE_PATH_MAX); + image_path[p_image]=p_path; + + bool all_ok=true; + for(int i=0;i<IMAGE_PATH_MAX;i++) { + if (image_path[i]==String()) { + all_ok=false; + } + } + + cube_map_valid=false; + + if (all_ok) { + + Image images[IMAGE_PATH_MAX]; + int w=0,h=0; + Image::Format format; + + for(int i=0;i<IMAGE_PATH_MAX;i++) { + Error err = ImageLoader::load_image(image_path[i],&images[i]); + if (err) { + ERR_PRINTS("Error loading image for skybox: "+image_path[i]); + return; + } + + if (i==0) { + w=images[0].get_width(); + h=images[0].get_height(); + format=images[0].get_format(); + } else { + if (images[i].get_width()!=w || images[i].get_height()!=h || images[i].get_format()!=format) { + ERR_PRINTS("Image size mismatch ("+itos(images[i].get_width())+","+itos(images[i].get_height())+":"+Image::get_format_name(images[i].get_format())+" when it should be "+itos(w)+","+itos(h)+":"+Image::get_format_name(format)+"): "+image_path[i]); + return; + } + } + } + + VS::get_singleton()->texture_allocate(cube_map,w,h,format,VS::TEXTURE_FLAG_FILTER|VS::TEXTURE_FLAG_CUBEMAP|VS::TEXTURE_FLAG_MIPMAPS); + for(int i=0;i<IMAGE_PATH_MAX;i++) { + VS::get_singleton()->texture_set_data(cube_map,images[i],VS::CubeMapSide(i)); + } + + cube_map_valid=true; + _radiance_changed(); + } + + +} + +String ImageSkyBox::get_image_path(ImagePath p_image) const { + + ERR_FAIL_INDEX_V(p_image,IMAGE_PATH_MAX,String()); + return image_path[p_image]; + +} + +RID ImageSkyBox::get_rid() const { + + return sky_box; +} + +void ImageSkyBox::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_image_path","image","path"),&ImageSkyBox::set_image_path); + ObjectTypeDB::bind_method(_MD("get_image_path","image"),&ImageSkyBox::get_image_path); + + List<String> extensions; + ImageLoader::get_recognized_extensions(&extensions); + String hints; + for(List<String>::Element *E=extensions.front();E;E=E->next()) { + if (hints!=String()) { + hints+=","; + } + hints+="*."+E->get(); + } + + ADD_PROPERTYI(PropertyInfo(Variant::STRING,"image_path/negative_x",PROPERTY_HINT_FILE,hints),_SCS("set_image_path"),_SCS("get_image_path"),IMAGE_PATH_NEGATIVE_X); + ADD_PROPERTYI(PropertyInfo(Variant::STRING,"image_path/positive_x",PROPERTY_HINT_FILE,hints),_SCS("set_image_path"),_SCS("get_image_path"),IMAGE_PATH_POSITIVE_X); + ADD_PROPERTYI(PropertyInfo(Variant::STRING,"image_path/negative_y",PROPERTY_HINT_FILE,hints),_SCS("set_image_path"),_SCS("get_image_path"),IMAGE_PATH_NEGATIVE_Y); + ADD_PROPERTYI(PropertyInfo(Variant::STRING,"image_path/positive_y",PROPERTY_HINT_FILE,hints),_SCS("set_image_path"),_SCS("get_image_path"),IMAGE_PATH_POSITIVE_Y); + ADD_PROPERTYI(PropertyInfo(Variant::STRING,"image_path/negative_z",PROPERTY_HINT_FILE,hints),_SCS("set_image_path"),_SCS("get_image_path"),IMAGE_PATH_NEGATIVE_Z); + ADD_PROPERTYI(PropertyInfo(Variant::STRING,"image_path/positive_z",PROPERTY_HINT_FILE,hints),_SCS("set_image_path"),_SCS("get_image_path"),IMAGE_PATH_POSITIVE_Z); + + BIND_CONSTANT( IMAGE_PATH_NEGATIVE_X ); + BIND_CONSTANT( IMAGE_PATH_POSITIVE_X ); + BIND_CONSTANT( IMAGE_PATH_NEGATIVE_Y ); + BIND_CONSTANT( IMAGE_PATH_POSITIVE_Y ); + BIND_CONSTANT( IMAGE_PATH_NEGATIVE_Z ); + BIND_CONSTANT( IMAGE_PATH_POSITIVE_Z ); + BIND_CONSTANT( IMAGE_PATH_MAX ); + +} + +ImageSkyBox::ImageSkyBox() { + + cube_map=VS::get_singleton()->texture_create(); + sky_box=VS::get_singleton()->skybox_create(); + cube_map_valid=false; +} + +ImageSkyBox::~ImageSkyBox() { + + VS::get_singleton()->free(cube_map); + VS::get_singleton()->free(sky_box); +} + diff --git a/scene/resources/sky_box.h b/scene/resources/sky_box.h new file mode 100644 index 0000000000..3a3dd1b2de --- /dev/null +++ b/scene/resources/sky_box.h @@ -0,0 +1,71 @@ +#ifndef SKYBOX_H +#define SKYBOX_H + +#include "scene/resources/texture.h" + +class SkyBox : public Resource { + OBJ_TYPE(SkyBox,Resource); + +public: + + enum RadianceSize { + RADIANCE_SIZE_256, + RADIANCE_SIZE_512, + RADIANCE_SIZE_1024, + RADIANCE_SIZE_2048, + RADIANCE_SIZE_MAX + }; +private: + + RadianceSize radiance_size; +protected: + static void _bind_methods(); + virtual void _radiance_changed()=0; +public: + + void set_radiance_size(RadianceSize p_size); + RadianceSize get_radiance_size() const; + SkyBox(); +}; + +VARIANT_ENUM_CAST(SkyBox::RadianceSize) + + +class ImageSkyBox : public SkyBox { + OBJ_TYPE(ImageSkyBox,SkyBox); + +public: + + enum ImagePath { + IMAGE_PATH_NEGATIVE_X, + IMAGE_PATH_POSITIVE_X, + IMAGE_PATH_NEGATIVE_Y, + IMAGE_PATH_POSITIVE_Y, + IMAGE_PATH_NEGATIVE_Z, + IMAGE_PATH_POSITIVE_Z, + IMAGE_PATH_MAX + }; +private: + RID cube_map; + RID sky_box; + bool cube_map_valid; + + String image_path[IMAGE_PATH_MAX]; +protected: + static void _bind_methods(); + virtual void _radiance_changed(); +public: + + void set_image_path(ImagePath p_image, const String &p_path); + String get_image_path(ImagePath p_image) const; + + virtual RID get_rid() const; + + ImageSkyBox(); + ~ImageSkyBox(); +}; + +VARIANT_ENUM_CAST(ImageSkyBox::ImagePath) + + +#endif // SKYBOX_H diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 1c708f9c11..cdb663b8f1 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -141,7 +141,7 @@ void StyleBoxTexture::draw(RID p_canvas_item,const Rect2& p_rect) const { r.pos.y-=expand_margin[MARGIN_TOP]; r.size.x+=expand_margin[MARGIN_LEFT]+expand_margin[MARGIN_RIGHT]; r.size.y+=expand_margin[MARGIN_TOP]+expand_margin[MARGIN_BOTTOM]; - VisualServer::get_singleton()->canvas_item_add_style_box( p_canvas_item,r,region_rect,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center,modulate); + VisualServer::get_singleton()->canvas_item_add_nine_patch( p_canvas_item,r,region_rect,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),VS::NINE_PATCH_STRETCH,VS::NINE_PATCH_STRETCH,draw_center,modulate); } void StyleBoxTexture::set_draw_center(bool p_draw) { @@ -423,127 +423,3 @@ StyleBoxFlat::~StyleBoxFlat() { } -//////////////// - - - -void StyleBoxImageMask::_bind_methods() { - - ObjectTypeDB::bind_method(_MD("set_image","image"),&StyleBoxImageMask::set_image); - ObjectTypeDB::bind_method(_MD("get_image"),&StyleBoxImageMask::get_image); - ObjectTypeDB::bind_method(_MD("set_expand","expand"),&StyleBoxImageMask::set_expand); - ObjectTypeDB::bind_method(_MD("get_expand"),&StyleBoxImageMask::get_expand); - ObjectTypeDB::bind_method(_MD("set_expand_margin_size","margin","size"),&StyleBoxImageMask::set_expand_margin_size); - ObjectTypeDB::bind_method(_MD("get_expand_margin_size","margin"),&StyleBoxImageMask::get_expand_margin_size); - - ADD_PROPERTY( PropertyInfo(Variant::IMAGE, "image"), _SCS("set_image"), _SCS("get_image")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL, "expand"), _SCS("set_expand"), _SCS("get_expand")); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "expand_margin/left", PROPERTY_HINT_RANGE,"0,2048,1" ), _SCS("set_expand_margin_size"),_SCS("get_expand_margin_size"), MARGIN_LEFT ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "expand_margin/right", PROPERTY_HINT_RANGE,"0,2048,1" ), _SCS("set_expand_margin_size"),_SCS("get_expand_margin_size"), MARGIN_RIGHT ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "expand_margin/top", PROPERTY_HINT_RANGE,"0,2048,1" ), _SCS("set_expand_margin_size"),_SCS("get_expand_margin_size"), MARGIN_TOP ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "expand_margin/bottom", PROPERTY_HINT_RANGE,"0,2048,1" ), _SCS("set_expand_margin_size"),_SCS("get_expand_margin_size"), MARGIN_BOTTOM ); - -} - - -bool StyleBoxImageMask::test_mask(const Point2& p_point, const Rect2& p_rect) const { - - if (image.empty()) - return false; - if (p_rect.size.x<1) - return false; - if (p_rect.size.y<1) - return false; - - Size2i imgsize(image.get_width(),image.get_height()); - if (imgsize.x<=0 || imgsize.y<=0) - return false; - - Point2i img_expand_size( imgsize.x - expand_margin[MARGIN_LEFT] - expand_margin[MARGIN_RIGHT], imgsize.y - expand_margin[MARGIN_TOP] - expand_margin[MARGIN_BOTTOM]); - Point2i rect_expand_size( p_rect.size.x - expand_margin[MARGIN_LEFT] - expand_margin[MARGIN_RIGHT], p_rect.size.y - expand_margin[MARGIN_TOP] - expand_margin[MARGIN_BOTTOM]); - if (rect_expand_size.x<1) - rect_expand_size.x=1; - if (rect_expand_size.y<1) - rect_expand_size.y=1; - - - Point2i click_pos; - - - //treat x - - if (p_point.x<p_rect.pos.x) - click_pos.x=0; - else if (expand) { - - if (p_point.x>=p_rect.pos.x+p_rect.size.x) - click_pos.x=imgsize.x-1; - else if ((p_point.x-p_rect.pos.x)<expand_margin[MARGIN_LEFT]) - click_pos.x=p_point.x; - else if ((p_point.x-(p_rect.pos.x+p_rect.size.x))<expand_margin[MARGIN_RIGHT]) - click_pos.x=imgsize.x-(p_point.x-(p_rect.pos.x+p_rect.size.x)); - else //expand - click_pos.x=(p_point.x-p_rect.pos.x-expand_margin[MARGIN_LEFT])*img_expand_size.x/rect_expand_size.x; - } else if ((p_point.x-p_rect.pos.x) > imgsize.x) - click_pos.x=imgsize.x; - - //treat y - - if (p_point.y<p_rect.pos.y) - click_pos.y=0; - else if (expand) { - - if (p_point.y>=p_rect.pos.y+p_rect.size.y) - click_pos.y=imgsize.y-1; - else if ((p_point.y-p_rect.pos.y)<expand_margin[MARGIN_TOP]) - click_pos.y=p_point.y; - else if ((p_point.y-(p_rect.pos.y+p_rect.size.y))<expand_margin[MARGIN_BOTTOM]) - click_pos.y=imgsize.y-(p_point.y-(p_rect.pos.y+p_rect.size.y)); - else //expand - click_pos.y=(p_point.y-p_rect.pos.y-expand_margin[MARGIN_TOP])*img_expand_size.y/rect_expand_size.y; - } else if ((p_point.y-p_rect.pos.y) > imgsize.y) - click_pos.y=imgsize.y; - - return image.get_pixel(click_pos.x,click_pos.y).gray()>0.5; - -} - - -void StyleBoxImageMask::set_image(const Image& p_image) { - - image=p_image; -} -Image StyleBoxImageMask::get_image() const { - - return image; -} - - -void StyleBoxImageMask::set_expand(bool p_expand) { - - expand=p_expand; -} -bool StyleBoxImageMask::get_expand() const { - - return expand; -} -void StyleBoxImageMask::set_expand_margin_size(Margin p_expand_margin,float p_size) { - - ERR_FAIL_INDEX(p_expand_margin,4); - expand_margin[p_expand_margin]=p_size; -} - - -float StyleBoxImageMask::get_expand_margin_size(Margin p_expand_margin) const { - - ERR_FAIL_INDEX_V(p_expand_margin,4,0); - return expand_margin[p_expand_margin]; -} - -StyleBoxImageMask::StyleBoxImageMask() { - - for (int i=0;i<4;i++) { - expand_margin[i]=0; - } - expand=true; -} diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index e8127ee3ea..8d3ba3a360 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -167,35 +167,5 @@ public: }; -class StyleBoxImageMask : public StyleBox { - - OBJ_TYPE( StyleBoxImageMask, StyleBox ); - virtual float get_style_margin(Margin p_margin) const { return 0; } - - Image image; - float expand_margin[4]; - bool expand; - -protected: - - static void _bind_methods(); - -public: - - virtual void draw(RID p_canvas_item,const Rect2& p_rect) const {} - virtual bool test_mask(const Point2& p_point, const Rect2& p_rect) const; - - void set_image(const Image& p_image); - Image get_image() const; - - void set_expand(bool p_expand); - bool get_expand() const; - void set_expand_margin_size(Margin p_expand_margin,float p_size); - float get_expand_margin_size(Margin p_expand_margin) const; - - StyleBoxImageMask(); - -}; - #endif diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index f6147462f8..bcfacc62fa 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -355,7 +355,30 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) { w=DVector<Color>::Write(); a[i]=array; } break; - case Mesh::ARRAY_FORMAT_BONES: + case Mesh::ARRAY_FORMAT_BONES: { + + + DVector<int> array; + array.resize(varr_len*4); + DVector<int>::Write w = array.write(); + + int idx=0; + for(List< Vertex >::Element *E=vertex_array.front();E;E=E->next(),idx+=4) { + + const Vertex &v=E->get(); + + ERR_CONTINUE( v.bones.size()!=4 ); + + for(int j=0;j<4;j++) { + w[idx+j]=v.bones[j]; + } + + } + + w=DVector<int>::Write(); + a[i]=array; + + } break; case Mesh::ARRAY_FORMAT_WEIGHTS: { @@ -367,18 +390,11 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) { for(List< Vertex >::Element *E=vertex_array.front();E;E=E->next(),idx+=4) { const Vertex &v=E->get(); + ERR_CONTINUE( v.weights.size()!=4 ); for(int j=0;j<4;j++) { - switch(i) { - case Mesh::ARRAY_WEIGHTS: { - ERR_CONTINUE( v.weights.size()!=4 ); - w[idx+j]=v.weights[j]; - } break; - case Mesh::ARRAY_BONES: { - ERR_CONTINUE( v.bones.size()!=4 ); - w[idx+j]=v.bones[j]; - } break; - } + + w[idx+j]=v.weights[j]; } } @@ -410,7 +426,7 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) { } - mesh->add_surface(primitive,a); + mesh->add_surface_from_arrays(primitive,a); if (material.is_valid()) mesh->surface_set_material(surface,material); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index f511e2ecef..c9c9d679b6 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -258,23 +258,13 @@ void ImageTexture::load(const String& p_path) { void ImageTexture::set_data(const Image& p_image) { VisualServer::get_singleton()->texture_set_data(texture,p_image); - VisualServer::get_singleton()->texture_set_reload_hook(texture,0,StringName()); //hook is erased if data is changed + _change_notify(); } void ImageTexture::_resource_path_changed() { String path=get_path(); - if (VS::get_singleton()->has_feature(VS::FEATURE_NEEDS_RELOAD_HOOK)) { - //this needs to be done much better, but probably will end up being deprecated as technology advances - if (path.is_resource_file() && ImageLoader::recognize(path.extension())) { - - //hook is set only if path is hookable - VisualServer::get_singleton()->texture_set_reload_hook(texture,get_instance_ID(),"_reload_hook"); - } else { - VisualServer::get_singleton()->texture_set_reload_hook(texture,0,StringName()); - } - } } Image ImageTexture::get_data() const { @@ -300,7 +290,7 @@ RID ImageTexture::get_rid() const { void ImageTexture::fix_alpha_edges() { - if (format==Image::FORMAT_RGBA /*&& !(flags&FLAG_CUBEMAP)*/) { + if (format==Image::FORMAT_RGBA8 /*&& !(flags&FLAG_CUBEMAP)*/) { Image img = get_data(); img.fix_alpha_edges(); @@ -310,7 +300,7 @@ void ImageTexture::fix_alpha_edges() { void ImageTexture::premultiply_alpha() { - if (format==Image::FORMAT_RGBA /*&& !(flags&FLAG_CUBEMAP)*/) { + if (format==Image::FORMAT_RGBA8 /*&& !(flags&FLAG_CUBEMAP)*/) { Image img = get_data(); img.premultiply_alpha(); @@ -337,7 +327,7 @@ void ImageTexture::shrink_x2_and_keep_size() { bool ImageTexture::has_alpha() const { - return ( format==Image::FORMAT_GRAYSCALE_ALPHA || format==Image::FORMAT_INDEXED_ALPHA || format==Image::FORMAT_RGBA ); + return ( format==Image::FORMAT_LA8 || format==Image::FORMAT_RGBA8 ); } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index abc2939f26..945541e102 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -54,7 +54,7 @@ public: FLAG_FILTER=VisualServer::TEXTURE_FLAG_FILTER, FLAG_ANISOTROPIC_FILTER=VisualServer::TEXTURE_FLAG_ANISOTROPIC_FILTER, FLAG_CONVERT_TO_LINEAR=VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR, - FLAG_VIDEO_SURFACE=VisualServer::TEXTURE_FLAG_VIDEO_SURFACE, + FLAG_VIDEO_SURFACE=VisualServer::TEXTURE_FLAG_USED_FOR_STREAMING, FLAGS_DEFAULT=FLAG_MIPMAPS|FLAG_REPEAT|FLAG_FILTER, FLAG_MIRRORED_REPEAT=VisualServer::TEXTURE_FLAG_MIRRORED_REPEAT }; |