diff options
Diffstat (limited to 'scene')
28 files changed, 937 insertions, 559 deletions
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 2acbed3b4e..ec3e059249 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -973,7 +973,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater return mc; } -void GIProbe::_plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material) { +void GIProbe::_plot_mesh(const Transform &p_xform, Ref<ArrayMesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material) { for (int i = 0; i < p_mesh->get_surface_count(); i++) { @@ -1067,7 +1067,7 @@ 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(); + Ref<ArrayMesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { Rect3 aabb = mesh->get_aabb(); @@ -1094,7 +1094,7 @@ void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) { for (int i = 0; i < meshes.size(); i += 2) { Transform mxf = meshes[i]; - Ref<Mesh> mesh = meshes[i + 1]; + Ref<ArrayMesh> mesh = meshes[i + 1]; if (!mesh.is_valid()) continue; @@ -1317,7 +1317,7 @@ void GIProbe::_create_debug_mesh(Baker *p_baker) { print_line("leaf voxels: " + itos(p_baker->leaf_voxel_count)); mm->set_instance_count(p_baker->leaf_voxel_count); - Ref<Mesh> mesh; + Ref<ArrayMesh> mesh; mesh.instance(); { diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index 3b05d9952b..b5ee86455e 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -145,7 +145,7 @@ private: struct PlotMesh { Ref<Material> override_material; Vector<Ref<Material> > instance_materials; - Ref<Mesh> mesh; + Ref<ArrayMesh> mesh; Transform local_xform; }; @@ -173,7 +173,7 @@ private: Vector<Color> _get_bake_texture(Ref<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 Rect3 &p_aabb, Baker *p_baker); - void _plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material); + void _plot_mesh(const Transform &p_xform, Ref<ArrayMesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material); 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); diff --git a/scene/3d/listener.cpp b/scene/3d/listener.cpp index 148afbffa2..c7d3bac2f8 100644 --- a/scene/3d/listener.cpp +++ b/scene/3d/listener.cpp @@ -152,7 +152,7 @@ bool Listener::_can_gizmo_scale() const { } RES Listener::_get_gizmo_geometry() const { - Ref<Mesh> mesh = memnew(Mesh); + Ref<ArrayMesh> mesh = memnew(ArrayMesh); return mesh; } diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp index 13fd852fe7..82f6f665db 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -187,7 +187,7 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { } } - debug_mesh = Ref<Mesh>(memnew(Mesh)); + debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); Array arr; arr.resize(Mesh::ARRAY_MAX); diff --git a/scene/3d/navigation_mesh.h b/scene/3d/navigation_mesh.h index c8f6d936aa..e5a3dc7b43 100644 --- a/scene/3d/navigation_mesh.h +++ b/scene/3d/navigation_mesh.h @@ -44,7 +44,7 @@ class NavigationMesh : public Resource { Vector<int> indices; }; Vector<Polygon> polygons; - Ref<Mesh> debug_mesh; + Ref<ArrayMesh> debug_mesh; struct _EdgeKey { diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp index d24aa6ae2a..345afd3edf 100644 --- a/scene/3d/ray_cast.cpp +++ b/scene/3d/ray_cast.cpp @@ -266,7 +266,7 @@ void RayCast::_create_debug_shape() { line_material->set_albedo(Color(1.0, 0.8, 0.6)); } - Ref<Mesh> mesh = memnew(Mesh); + Ref<ArrayMesh> mesh = memnew(ArrayMesh); MeshInstance *mi = memnew(MeshInstance); mi->set_mesh(mesh); @@ -287,7 +287,7 @@ void RayCast::_update_debug_shape() { if (!mi->get_mesh().is_valid()) return; - Ref<Mesh> mesh = mi->get_mesh(); + Ref<ArrayMesh> mesh = mi->get_mesh(); if (mesh->get_surface_count() > 0) mesh->surface_remove(0); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index b5d059eaf5..95f65f31d6 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -582,8 +582,6 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) { ERR_EXPLAIN("GraphNode must be the child of a GraphEdit node."); ERR_FAIL_COND(get_parent_control() == NULL); - print_line("INPUT EVENT BUTTON"); - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { Vector2 mpos = Vector2(mb->get_position().x, mb->get_position().y); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 371cf929fe..2f0c7b9aaf 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -931,23 +931,26 @@ void ItemList::_notification(int p_what) { rcache.size.width = width - rcache.position.x; } - Rect2 r = rcache; - r.position += base_ofs; - - // Use stylebox to dimension potential bg color, even if not selected - r.position.x -= sbsel->get_margin(MARGIN_LEFT); - r.size.x += sbsel->get_margin(MARGIN_LEFT) + sbsel->get_margin(MARGIN_RIGHT); - r.position.y -= sbsel->get_margin(MARGIN_TOP); - r.size.y += sbsel->get_margin(MARGIN_TOP) + sbsel->get_margin(MARGIN_BOTTOM); - if (items[i].selected) { + Rect2 r = rcache; + r.position += base_ofs; + + // Use stylebox to dimension potential bg color + r.position.x -= sbsel->get_margin(MARGIN_LEFT); + r.size.x += sbsel->get_margin(MARGIN_LEFT) + sbsel->get_margin(MARGIN_RIGHT); + r.position.y -= sbsel->get_margin(MARGIN_TOP); + r.size.y += sbsel->get_margin(MARGIN_TOP) + sbsel->get_margin(MARGIN_BOTTOM); draw_style_box(sbsel, r); } + if (items[i].custom_bg.a > 0.001) { - r.position.x += 2; - r.size.x -= 4; - r.position.y += 2; - r.size.y -= 4; + + Rect2 r = rcache; + r.position += base_ofs; + + // Size rect to make the align the temperature colors + r.position.y -= vseparation / 2; + r.size.y += vseparation; draw_rect(r, items[i].custom_bg); } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index d3a49b06d5..0b8595de42 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -264,7 +264,7 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int cw = tab_size * font->get_char_size(' ').width; } - if (end > 0 && w + cw + wofs > p_width) { + if (end > 0 && w + cw + begin > p_width) { break; //don't allow lines longer than assigned width } diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index 96a3519840..f7a255cd33 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -839,12 +839,12 @@ Ref<Material> SceneTree::get_debug_collision_material() { return collision_material; } -Ref<Mesh> SceneTree::get_debug_contact_mesh() { +Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() { if (debug_contact_mesh.is_valid()) return debug_contact_mesh; - debug_contact_mesh = Ref<Mesh>(memnew(Mesh)); + debug_contact_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); Ref<SpatialMaterial> mat = memnew(SpatialMaterial); /*mat->set_flag(Material::FLAG_UNSHADED,true); diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index 5d42c66652..2ea79bf945 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -33,6 +33,7 @@ #include "io/networked_multiplayer_peer.h" #include "os/main_loop.h" #include "os/thread_safe.h" +#include "scene/resources/mesh.h" #include "scene/resources/world.h" #include "scene/resources/world_2d.h" #include "self_list.h" @@ -169,7 +170,7 @@ private: Color debug_collision_contact_color; Color debug_navigation_color; Color debug_navigation_disabled_color; - Ref<Mesh> debug_contact_mesh; + Ref<ArrayMesh> debug_contact_mesh; Ref<Material> navigation_material; Ref<Material> navigation_disabled_material; Ref<Material> collision_material; @@ -406,7 +407,7 @@ public: Ref<Material> get_debug_navigation_material(); Ref<Material> get_debug_navigation_disabled_material(); Ref<Material> get_debug_collision_material(); - Ref<Mesh> get_debug_contact_mesh(); + Ref<ArrayMesh> get_debug_contact_mesh(); int get_collision_debug_contact_count() { return collision_debug_contacts; } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index ec36cf48bc..95fad83a28 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -117,7 +117,11 @@ bool ViewportTexture::has_alpha() const { return false; } +Ref<Image> ViewportTexture::get_data() const { + ERR_FAIL_COND_V(!vp, Ref<Image>()); + return VS::get_singleton()->texture_get_data(vp->texture_rid); +} void ViewportTexture::set_flags(uint32_t p_flags) { if (!vp) @@ -2516,6 +2520,16 @@ bool Viewport::get_hdr() const { return hdr; } +void Viewport::set_usage(Usage p_usage) { + + usage = p_usage; + VS::get_singleton()->viewport_set_usage(viewport, VS::ViewportUsage(p_usage)); +} + +Viewport::Usage Viewport::get_usage() const { + return usage; +} + void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_size", "size"), &Viewport::set_size); @@ -2569,6 +2583,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_hdr", "enable"), &Viewport::set_hdr); ClassDB::bind_method(D_METHOD("get_hdr"), &Viewport::get_hdr); + ClassDB::bind_method(D_METHOD("set_usage", "usage"), &Viewport::set_usage); + ClassDB::bind_method(D_METHOD("get_usage"), &Viewport::get_usage); + ClassDB::bind_method(D_METHOD("get_texture:ViewportTexture"), &Viewport::get_texture); ClassDB::bind_method(D_METHOD("set_physics_object_picking", "enable"), &Viewport::set_physics_object_picking); @@ -2622,6 +2639,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x"), "set_msaa", "get_msaa"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_ENUM, "2D,2D No-Sampling,3D,3D No-Effects"), "set_usage", "get_usage"); ADD_GROUP("Render Target", "render_target_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_v_flip"), "set_vflip", "get_vflip"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_clear_on_new_frame"), "set_clear_on_new_frame", "get_clear_on_new_frame"); @@ -2730,6 +2748,8 @@ Viewport::Viewport() { msaa = MSAA_DISABLED; hdr = false; + + usage = USAGE_3D; } Viewport::~Viewport() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 7470cefb49..e619199424 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -77,6 +77,8 @@ public: virtual void set_flags(uint32_t p_flags); virtual uint32_t get_flags() const; + virtual Ref<Image> get_data() const; + ViewportTexture(); ~ViewportTexture(); }; @@ -113,6 +115,13 @@ public: MSAA_16X, }; + enum Usage { + USAGE_2D, + USAGE_2D_NO_SAMPLING, + USAGE_3D, + USAGE_3D_NO_EFFECTS, + }; + private: friend class ViewportTexture; @@ -195,6 +204,8 @@ private: RID texture_rid; uint32_t texture_flags; + Usage usage; + int shadow_atlas_size; ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4]; @@ -416,6 +427,9 @@ public: virtual String get_configuration_warning() const; + void set_usage(Usage p_usage); + Usage get_usage() const; + Viewport(); ~Viewport(); }; @@ -423,5 +437,6 @@ public: VARIANT_ENUM_CAST(Viewport::UpdateMode); VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); +VARIANT_ENUM_CAST(Viewport::Usage); #endif diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 0a3f64eacd..9f078072d7 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -523,11 +523,12 @@ void register_scene_types() { ClassDB::register_virtual_class<Shader>(); #ifndef _3D_DISABLED - ClassDB::register_class<Mesh>(); - ClassDB::register_class<QuadMesh>(); + ClassDB::register_virtual_class<Mesh>(); + ClassDB::register_class<ArrayMesh>(); ClassDB::register_virtual_class<Material>(); ClassDB::register_class<SpatialMaterial>(); ClassDB::add_compatibility_class("FixedSpatialMaterial", "SpatialMaterial"); + ClassDB::add_compatibility_class("Mesh", "ArrayMesh"); SceneTree::add_idle_callback(SpatialMaterial::flush_changes); SpatialMaterial::init_shaders(); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 66f913f347..e40fc0d4be 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -217,6 +217,7 @@ 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()); + _change_notify(); } bool Environment::is_adjustment_enabled() const { @@ -283,12 +284,39 @@ void Environment::_validate_property(PropertyInfo &property) const { property.usage = PROPERTY_USAGE_NOEDITOR; } } + + static const char *hide_prefixes[] = { + "fog_", + "auto_exposure_", + "ss_reflections_", + "ssao_", + "dof_blur_far_", + "dof_blur_near_", + "glow_", + "adjustment_", + NULL + + }; + + const char **prefixes = hide_prefixes; + while (*prefixes) { + String prefix = String(*prefixes); + + String enabled = prefix + "enabled"; + if (property.name.begins_with(prefix) && property.name != enabled && !bool(get(enabled))) { + property.usage = PROPERTY_USAGE_NOEDITOR; + return; + } + + prefixes++; + } } 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); + _change_notify(); } bool Environment::is_ssr_enabled() const { @@ -360,6 +388,7 @@ 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); + _change_notify(); } bool Environment::is_ssao_enabled() const { @@ -453,6 +482,7 @@ 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); + _change_notify(); } bool Environment::is_glow_enabled() const { @@ -558,6 +588,7 @@ 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)); + _change_notify(); } bool Environment::is_dof_blur_far_enabled() const { @@ -610,6 +641,7 @@ 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)); + _change_notify(); } bool Environment::is_dof_blur_near_enabled() const { @@ -661,6 +693,138 @@ Environment::DOFBlurQuality Environment::get_dof_blur_near_quality() const { return dof_blur_near_quality; } +void Environment::set_fog_enabled(bool p_enabled) { + + fog_enabled = p_enabled; + VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount); + _change_notify(); +} + +bool Environment::is_fog_enabled() const { + + return fog_enabled; +} + +void Environment::set_fog_color(const Color &p_color) { + + fog_color = p_color; + VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount); +} +Color Environment::get_fog_color() const { + + return fog_color; +} + +void Environment::set_fog_sun_color(const Color &p_color) { + + fog_sun_color = p_color; + VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount); +} +Color Environment::get_fog_sun_color() const { + + return fog_sun_color; +} + +void Environment::set_fog_sun_amount(float p_amount) { + + fog_sun_amount = p_amount; + VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount); +} +float Environment::get_fog_sun_amount() const { + + return fog_sun_amount; +} + +void Environment::set_fog_depth_enabled(bool p_enabled) { + + fog_depth_enabled = p_enabled; + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); +} +bool Environment::is_fog_depth_enabled() const { + + return fog_depth_enabled; +} + +void Environment::set_fog_depth_begin(float p_distance) { + + fog_depth_begin = p_distance; + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); +} +float Environment::get_fog_depth_begin() const { + + return fog_depth_begin; +} + +void Environment::set_fog_depth_curve(float p_curve) { + + fog_depth_curve = p_curve; + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); +} +float Environment::get_fog_depth_curve() const { + + return fog_depth_curve; +} + +void Environment::set_fog_transmit_enabled(bool p_enabled) { + + fog_transmit_enabled = p_enabled; + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); +} +bool Environment::is_fog_transmit_enabled() const { + + return fog_transmit_enabled; +} + +void Environment::set_fog_transmit_curve(float p_curve) { + + fog_transmit_curve = p_curve; + VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve); +} +float Environment::get_fog_transmit_curve() const { + + return fog_transmit_curve; +} + +void Environment::set_fog_height_enabled(bool p_enabled) { + + fog_height_enabled = p_enabled; + VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve); +} +bool Environment::is_fog_height_enabled() const { + + return fog_height_enabled; +} + +void Environment::set_fog_height_min(float p_distance) { + + fog_height_min = p_distance; + VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve); +} +float Environment::get_fog_height_min() const { + + return fog_height_min; +} + +void Environment::set_fog_height_max(float p_distance) { + + fog_height_max = p_distance; + VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve); +} +float Environment::get_fog_height_max() const { + + return fog_height_max; +} + +void Environment::set_fog_height_curve(float p_distance) { + + fog_height_curve = p_distance; + VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve); +} +float Environment::get_fog_height_curve() const { + + return fog_height_curve; +} + void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background); @@ -695,6 +859,60 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution"); + ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled); + ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled); + + ClassDB::bind_method(D_METHOD("set_fog_color", "color"), &Environment::set_fog_color); + ClassDB::bind_method(D_METHOD("get_fog_color"), &Environment::get_fog_color); + + ClassDB::bind_method(D_METHOD("set_fog_sun_color", "color"), &Environment::set_fog_sun_color); + ClassDB::bind_method(D_METHOD("get_fog_sun_color"), &Environment::get_fog_sun_color); + + ClassDB::bind_method(D_METHOD("set_fog_sun_amount", "amount"), &Environment::set_fog_sun_amount); + ClassDB::bind_method(D_METHOD("get_fog_sun_amount"), &Environment::get_fog_sun_amount); + + ClassDB::bind_method(D_METHOD("set_fog_depth_enabled", "enabled"), &Environment::set_fog_depth_enabled); + ClassDB::bind_method(D_METHOD("is_fog_depth_enabled"), &Environment::is_fog_depth_enabled); + + ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "distance"), &Environment::set_fog_depth_begin); + ClassDB::bind_method(D_METHOD("get_fog_depth_begin"), &Environment::get_fog_depth_begin); + + ClassDB::bind_method(D_METHOD("set_fog_depth_curve", "curve"), &Environment::set_fog_depth_curve); + ClassDB::bind_method(D_METHOD("get_fog_depth_curve"), &Environment::get_fog_depth_curve); + + ClassDB::bind_method(D_METHOD("set_fog_transmit_enabled", "enabled"), &Environment::set_fog_transmit_enabled); + ClassDB::bind_method(D_METHOD("is_fog_transmit_enabled"), &Environment::is_fog_transmit_enabled); + + ClassDB::bind_method(D_METHOD("set_fog_transmit_curve", "curve"), &Environment::set_fog_transmit_curve); + ClassDB::bind_method(D_METHOD("get_fog_transmit_curve"), &Environment::get_fog_transmit_curve); + + ClassDB::bind_method(D_METHOD("set_fog_height_enabled", "enabled"), &Environment::set_fog_height_enabled); + ClassDB::bind_method(D_METHOD("is_fog_height_enabled"), &Environment::is_fog_height_enabled); + + ClassDB::bind_method(D_METHOD("set_fog_height_min", "height"), &Environment::set_fog_height_min); + ClassDB::bind_method(D_METHOD("get_fog_height_min"), &Environment::get_fog_height_min); + + ClassDB::bind_method(D_METHOD("set_fog_height_max", "height"), &Environment::set_fog_height_max); + ClassDB::bind_method(D_METHOD("get_fog_height_max"), &Environment::get_fog_height_max); + + ClassDB::bind_method(D_METHOD("set_fog_height_curve", "curve"), &Environment::set_fog_height_curve); + ClassDB::bind_method(D_METHOD("get_fog_height_curve"), &Environment::get_fog_height_curve); + + ADD_GROUP("Fog", "fog_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_color"), "set_fog_color", "get_fog_color"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_sun_color"), "set_fog_sun_color", "get_fog_sun_color"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_height_enabled"), "set_fog_height_enabled", "is_fog_height_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1"), "set_fog_height_min", "get_fog_height_min"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1"), "set_fog_height_max", "get_fog_height_max"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve"); + ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper); ClassDB::bind_method(D_METHOD("get_tonemapper"), &Environment::get_tonemapper); @@ -997,6 +1215,27 @@ Environment::Environment() { dof_blur_near_transition = 1; dof_blur_near_amount = 0.1; dof_blur_near_quality = DOF_BLUR_QUALITY_MEDIUM; + + fog_enabled = false; + fog_color = Color(0.5, 0.5, 0.5); + fog_sun_color = Color(0.8, 0.8, 0.0); + fog_sun_amount = 0; + + fog_depth_enabled = true; + + fog_depth_begin = 10; + fog_depth_curve = 1; + + fog_transmit_enabled = false; + fog_transmit_curve = 1; + + fog_height_enabled = false; + fog_height_min = 0; + fog_height_max = 100; + fog_height_curve = 1; + + set_fog_color(Color(0.5, 0.6, 0.7)); + set_fog_sun_color(Color(1.0, 0.9, 0.7)); } Environment::~Environment() { diff --git a/scene/resources/environment.h b/scene/resources/environment.h index d9141ccd9c..7df3458231 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -138,6 +138,23 @@ private: float dof_blur_near_amount; DOFBlurQuality dof_blur_near_quality; + bool fog_enabled; + Color fog_color; + Color fog_sun_color; + float fog_sun_amount; + + bool fog_depth_enabled; + float fog_depth_begin; + float fog_depth_curve; + + bool fog_transmit_enabled; + float fog_transmit_curve; + + bool fog_height_enabled; + float fog_height_min; + float fog_height_max; + float fog_height_curve; + protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const; @@ -307,6 +324,45 @@ public: void set_dof_blur_near_quality(DOFBlurQuality p_quality); DOFBlurQuality get_dof_blur_near_quality() const; + void set_fog_enabled(bool p_enabled); + bool is_fog_enabled() const; + + void set_fog_color(const Color &p_color); + Color get_fog_color() const; + + void set_fog_sun_color(const Color &p_color); + Color get_fog_sun_color() const; + + void set_fog_sun_amount(float p_amount); + float get_fog_sun_amount() const; + + void set_fog_depth_enabled(bool p_enabled); + bool is_fog_depth_enabled() const; + + void set_fog_depth_begin(float p_distance); + float get_fog_depth_begin() const; + + void set_fog_depth_curve(float p_curve); + float get_fog_depth_curve() const; + + void set_fog_transmit_enabled(bool p_enabled); + bool is_fog_transmit_enabled() const; + + void set_fog_transmit_curve(float p_curve); + float get_fog_transmit_curve() const; + + void set_fog_height_enabled(bool p_enabled); + bool is_fog_height_enabled() const; + + void set_fog_height_min(float p_distance); + float get_fog_height_min() const; + + void set_fog_height_max(float p_distance); + float get_fog_height_max() const; + + void set_fog_height_curve(float p_distance); + float get_fog_height_curve() const; + virtual RID get_rid() const; Environment(); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index a9205fd571..ce88325539 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -193,7 +193,6 @@ void SpatialMaterial::init_shaders() { shader_names->depth_scale = "depth_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"; @@ -268,7 +267,12 @@ void SpatialMaterial::_update_shader() { case BLEND_MODE_MUL: code += "blend_mul"; break; } - switch (depth_draw_mode) { + DepthDrawMode ddm = depth_draw_mode; + if (features[FEATURE_REFRACTION]) { + ddm = DEPTH_DRAW_ALWAYS; + } + + switch (ddm) { 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; @@ -322,6 +326,11 @@ void SpatialMaterial::_update_shader() { code += "uniform float emission_energy;\n"; } + if (features[FEATURE_REFRACTION]) { + code += "uniform sampler2D texture_refraction;\n"; + code += "uniform float refraction : hint_range(-16,16);\n"; + } + if (features[FEATURE_NORMAL_MAPPING]) { code += "uniform sampler2D texture_normal : hint_normal;\n"; code += "uniform float normal_scale : hint_range(-16,16);\n"; @@ -489,17 +498,37 @@ void SpatialMaterial::_update_shader() { } code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n"; - if (features[FEATURE_TRANSPARENT]) { - code += "\tALPHA = albedo.a * albedo_tex.a;\n"; + code += "\tfloat metallic_tex = texture(texture_metallic,base_uv).r;\n"; + code += "\tMETALLIC = metallic_tex * metallic;\n"; + code += "\tfloat roughness_tex = texture(texture_roughness,base_uv).r;\n"; + code += "\tROUGHNESS = roughness_tex * roughness;\n"; + code += "\tSPECULAR = specular;\n"; + + if (features[FEATURE_NORMAL_MAPPING]) { + code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n"; + code += "\tNORMALMAP_DEPTH = normal_scale;\n"; } if (features[FEATURE_EMISSION]) { code += "\tEMISSION = (emission.rgb+texture(texture_emission,base_uv).rgb)*emission_energy;\n"; } - if (features[FEATURE_NORMAL_MAPPING]) { - code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n"; - code += "\tNORMALMAP_DEPTH = normal_scale;\n"; + if (features[FEATURE_REFRACTION]) { + + if (features[FEATURE_NORMAL_MAPPING]) { + code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) ) * SIDE;\n"; + } else { + code += "\tvec3 ref_normal = NORMAL;\n"; + } + + code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * texture(texture_refraction,base_uv).r * refraction;\n"; + code += "\tfloat ref_amount = 1.0 - albedo.a * albedo_tex.a;\n"; + code += "\tEMISSION += textureLod(SCREEN_TEXTURE,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n"; + code += "\tALBEDO *= 1.0 - ref_amount;\n"; + code += "\tALPHA = 1.0;\n"; + + } else if (features[FEATURE_TRANSPARENT]) { + code += "\tALPHA = albedo.a * albedo_tex.a;\n"; } if (features[FEATURE_RIM]) { @@ -557,12 +586,6 @@ void SpatialMaterial::_update_shader() { code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n"; } - code += "\tfloat metallic_tex = texture(texture_metallic,base_uv).r;\n"; - code += "\tMETALLIC = metallic_tex * metallic;\n"; - code += "\tfloat roughness_tex = texture(texture_roughness,base_uv).r;\n"; - code += "\tROUGHNESS = roughness_tex * roughness;\n"; - code += "\tSPECULAR = specular;\n"; - code += "}\n"; ShaderData shader_data; @@ -777,16 +800,6 @@ float SpatialMaterial::get_refraction() const { return refraction; } -void SpatialMaterial::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); -} -float SpatialMaterial::get_refraction_roughness() const { - - return refraction_roughness; -} - void SpatialMaterial::set_detail_uv(DetailUV p_detail_uv) { if (detail_uv == p_detail_uv) @@ -1125,9 +1138,6 @@ void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &SpatialMaterial::set_refraction); ClassDB::bind_method(D_METHOD("get_refraction"), &SpatialMaterial::get_refraction); - ClassDB::bind_method(D_METHOD("set_refraction_roughness", "refraction_roughness"), &SpatialMaterial::set_refraction_roughness); - ClassDB::bind_method(D_METHOD("get_refraction_roughness"), &SpatialMaterial::get_refraction_roughness); - ClassDB::bind_method(D_METHOD("set_line_width", "line_width"), &SpatialMaterial::set_line_width); ClassDB::bind_method(D_METHOD("get_line_width"), &SpatialMaterial::get_line_width); @@ -1277,8 +1287,7 @@ void SpatialMaterial::_bind_methods() { ADD_GROUP("Refraction", "refraction_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_displacement", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_refraction_roughness", "get_refraction_roughness"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_REFRACTION); ADD_GROUP("Detail", "detail_"); @@ -1381,8 +1390,7 @@ SpatialMaterial::SpatialMaterial() set_anisotropy(0); set_depth_scale(0.05); set_subsurface_scattering_strength(0); - set_refraction(0); - set_refraction_roughness(0); + set_refraction(0.05); set_line_width(1); set_point_size(1); set_uv1_offset(Vector2(0, 0)); diff --git a/scene/resources/material.h b/scene/resources/material.h index e72d3d455b..b6e85c8332 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -248,7 +248,6 @@ private: StringName depth_scale; StringName subsurface_scattering_strength; StringName refraction; - StringName refraction_roughness; StringName point_size; StringName uv1_scale; StringName uv1_offset; @@ -288,7 +287,6 @@ private: float depth_scale; float subsurface_scattering_strength; float refraction; - float refraction_roughness; float line_width; float point_size; int particles_anim_h_frames; @@ -380,9 +378,6 @@ public: void set_refraction(float p_refraction); float get_refraction() const; - void set_refraction_roughness(float p_refraction_roughness); - float get_refraction_roughness() const; - void set_line_width(float p_line_width); float get_line_width() const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 4846d84b33..7f3b4d2759 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -32,6 +32,390 @@ #include "scene/resources/convex_polygon_shape.h" #include "surface_tool.h" +void Mesh::_clear_triangle_mesh() { + + triangle_mesh.unref(); + ; +} + +Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { + + if (triangle_mesh.is_valid()) + return triangle_mesh; + + int facecount = 0; + + for (int i = 0; i < get_surface_count(); i++) { + + if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) + continue; + + if (surface_get_format(i) & ARRAY_FORMAT_INDEX) { + + facecount += surface_get_array_index_len(i); + } else { + + facecount += surface_get_array_len(i); + } + } + + if (facecount == 0 || (facecount % 3) != 0) + return triangle_mesh; + + PoolVector<Vector3> faces; + faces.resize(facecount); + PoolVector<Vector3>::Write facesw = faces.write(); + + int widx = 0; + + for (int i = 0; i < get_surface_count(); i++) { + + if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) + continue; + + Array a = surface_get_arrays(i); + + int vc = surface_get_array_len(i); + PoolVector<Vector3> vertices = a[ARRAY_VERTEX]; + PoolVector<Vector3>::Read vr = vertices.read(); + + if (surface_get_format(i) & ARRAY_FORMAT_INDEX) { + + int ic = surface_get_array_index_len(i); + PoolVector<int> indices = a[ARRAY_INDEX]; + PoolVector<int>::Read ir = indices.read(); + + for (int i = 0; i < ic; i++) { + int index = ir[i]; + facesw[widx++] = vr[index]; + } + + } else { + + for (int i = 0; i < vc; i++) + facesw[widx++] = vr[i]; + } + } + + facesw = PoolVector<Vector3>::Write(); + + triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); + triangle_mesh->create(faces); + + return triangle_mesh; +} + +PoolVector<Face3> Mesh::get_faces() const { + + Ref<TriangleMesh> tm = generate_triangle_mesh(); + if (tm.is_valid()) + return tm->get_faces(); + return PoolVector<Face3>(); + /* + for (int i=0;i<surfaces.size();i++) { + + if (VisualServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != VisualServer::PRIMITIVE_TRIANGLES ) + continue; + + PoolVector<int> indices; + PoolVector<Vector3> vertices; + + vertices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_VERTEX); + + int len=VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, i); + bool has_indices; + + if (len>0) { + + indices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_INDEX); + has_indices=true; + + } else { + + len=vertices.size(); + has_indices=false; + } + + if (len<=0) + continue; + + PoolVector<int>::Read indicesr = indices.read(); + const int *indicesptr = indicesr.ptr(); + + PoolVector<Vector3>::Read verticesr = vertices.read(); + const Vector3 *verticesptr = verticesr.ptr(); + + int old_faces=faces.size(); + int new_faces=old_faces+(len/3); + + faces.resize(new_faces); + + PoolVector<Face3>::Write facesw = faces.write(); + Face3 *facesptr=facesw.ptr(); + + + for (int i=0;i<len/3;i++) { + + Face3 face; + + for (int j=0;j<3;j++) { + + int idx=i*3+j; + face.vertex[j] = has_indices ? verticesptr[ indicesptr[ idx ] ] : verticesptr[idx]; + } + + facesptr[i+old_faces]=face; + } + + } +*/ +} + +Ref<Shape> Mesh::create_convex_shape() const { + + PoolVector<Vector3> vertices; + + for (int i = 0; i < get_surface_count(); i++) { + + Array a = surface_get_arrays(i); + PoolVector<Vector3> v = a[ARRAY_VERTEX]; + vertices.append_array(v); + } + + Ref<ConvexPolygonShape> shape = memnew(ConvexPolygonShape); + shape->set_points(vertices); + return shape; +} + +Ref<Shape> Mesh::create_trimesh_shape() const { + + PoolVector<Face3> faces = get_faces(); + if (faces.size() == 0) + return Ref<Shape>(); + + PoolVector<Vector3> face_points; + face_points.resize(faces.size() * 3); + + for (int i = 0; i < face_points.size(); i++) { + + Face3 f = faces.get(i / 3); + face_points.set(i, f.vertex[i % 3]); + } + + Ref<ConcavePolygonShape> shape = memnew(ConcavePolygonShape); + shape->set_faces(face_points); + return shape; +} + +Ref<Mesh> Mesh::create_outline(float p_margin) const { + + Array arrays; + int index_accum = 0; + for (int i = 0; i < get_surface_count(); i++) { + + if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) + continue; + + Array a = surface_get_arrays(i); + int vcount = 0; + + if (i == 0) { + arrays = a; + PoolVector<Vector3> v = a[ARRAY_VERTEX]; + index_accum += v.size(); + } else { + + for (int j = 0; j < arrays.size(); j++) { + + if (arrays[j].get_type() == Variant::NIL || a[j].get_type() == Variant::NIL) { + //mismatch, do not use + arrays[j] = Variant(); + continue; + } + + switch (j) { + + case ARRAY_VERTEX: + case ARRAY_NORMAL: { + + PoolVector<Vector3> dst = arrays[j]; + PoolVector<Vector3> src = a[j]; + if (j == ARRAY_VERTEX) + vcount = src.size(); + if (dst.size() == 0 || src.size() == 0) { + arrays[j] = Variant(); + continue; + } + dst.append_array(src); + arrays[j] = dst; + } break; + case ARRAY_TANGENT: + case ARRAY_BONES: + case ARRAY_WEIGHTS: { + + PoolVector<real_t> dst = arrays[j]; + PoolVector<real_t> src = a[j]; + if (dst.size() == 0 || src.size() == 0) { + arrays[j] = Variant(); + continue; + } + dst.append_array(src); + arrays[j] = dst; + + } break; + case ARRAY_COLOR: { + PoolVector<Color> dst = arrays[j]; + PoolVector<Color> src = a[j]; + if (dst.size() == 0 || src.size() == 0) { + arrays[j] = Variant(); + continue; + } + dst.append_array(src); + arrays[j] = dst; + + } break; + case ARRAY_TEX_UV: + case ARRAY_TEX_UV2: { + PoolVector<Vector2> dst = arrays[j]; + PoolVector<Vector2> src = a[j]; + if (dst.size() == 0 || src.size() == 0) { + arrays[j] = Variant(); + continue; + } + dst.append_array(src); + arrays[j] = dst; + + } break; + case ARRAY_INDEX: { + PoolVector<int> dst = arrays[j]; + PoolVector<int> src = a[j]; + if (dst.size() == 0 || src.size() == 0) { + arrays[j] = Variant(); + continue; + } + { + int ss = src.size(); + PoolVector<int>::Write w = src.write(); + for (int k = 0; k < ss; k++) { + w[k] += index_accum; + } + } + dst.append_array(src); + arrays[j] = dst; + index_accum += vcount; + + } break; + } + } + } + } + + { + PoolVector<int>::Write ir; + PoolVector<int> indices = arrays[ARRAY_INDEX]; + bool has_indices = false; + PoolVector<Vector3> vertices = arrays[ARRAY_VERTEX]; + int vc = vertices.size(); + ERR_FAIL_COND_V(!vc, Ref<ArrayMesh>()); + PoolVector<Vector3>::Write r = vertices.write(); + + if (indices.size()) { + vc = indices.size(); + ir = indices.write(); + has_indices = true; + } + + Map<Vector3, Vector3> normal_accum; + + //fill normals with triangle normals + for (int i = 0; i < vc; i += 3) { + + Vector3 t[3]; + + if (has_indices) { + t[0] = r[ir[i + 0]]; + t[1] = r[ir[i + 1]]; + t[2] = r[ir[i + 2]]; + } else { + t[0] = r[i + 0]; + t[1] = r[i + 1]; + t[2] = r[i + 2]; + } + + Vector3 n = Plane(t[0], t[1], t[2]).normal; + + for (int j = 0; j < 3; j++) { + + Map<Vector3, Vector3>::Element *E = normal_accum.find(t[j]); + if (!E) { + normal_accum[t[j]] = n; + } else { + float d = n.dot(E->get()); + if (d < 1.0) + E->get() += n * (1.0 - d); + //E->get()+=n; + } + } + } + + //normalize + + for (Map<Vector3, Vector3>::Element *E = normal_accum.front(); E; E = E->next()) { + E->get().normalize(); + } + + //displace normals + int vc2 = vertices.size(); + + for (int i = 0; i < vc2; i++) { + + Vector3 t = r[i]; + + Map<Vector3, Vector3>::Element *E = normal_accum.find(t); + ERR_CONTINUE(!E); + + t += E->get() * p_margin; + r[i] = t; + } + + r = PoolVector<Vector3>::Write(); + arrays[ARRAY_VERTEX] = vertices; + + if (!has_indices) { + + PoolVector<int> new_indices; + new_indices.resize(vertices.size()); + PoolVector<int>::Write iw = new_indices.write(); + + for (int j = 0; j < vc2; j += 3) { + + iw[j] = j; + iw[j + 1] = j + 2; + iw[j + 2] = j + 1; + } + + iw = PoolVector<int>::Write(); + arrays[ARRAY_INDEX] = new_indices; + + } else { + + for (int j = 0; j < vc; j += 3) { + + SWAP(ir[j + 1], ir[j + 2]); + } + ir = PoolVector<int>::Write(); + arrays[ARRAY_INDEX] = indices; + } + } + + Ref<ArrayMesh> newmesh = memnew(ArrayMesh); + newmesh->add_surface_from_arrays(PRIMITIVE_TRIANGLES, arrays); + return newmesh; +} + +Mesh::Mesh() { +} + static const char *_array_name[] = { "vertex_array", "normal_array", @@ -45,34 +429,34 @@ static const char *_array_name[] = { NULL }; -static const Mesh::ArrayType _array_types[] = { - - Mesh::ARRAY_VERTEX, - Mesh::ARRAY_NORMAL, - Mesh::ARRAY_TANGENT, - Mesh::ARRAY_COLOR, - Mesh::ARRAY_TEX_UV, - Mesh::ARRAY_TEX_UV2, - Mesh::ARRAY_BONES, - Mesh::ARRAY_WEIGHTS, - Mesh::ARRAY_INDEX +static const ArrayMesh::ArrayType _array_types[] = { + + ArrayMesh::ARRAY_VERTEX, + ArrayMesh::ARRAY_NORMAL, + ArrayMesh::ARRAY_TANGENT, + ArrayMesh::ARRAY_COLOR, + ArrayMesh::ARRAY_TEX_UV, + ArrayMesh::ARRAY_TEX_UV2, + ArrayMesh::ARRAY_BONES, + ArrayMesh::ARRAY_WEIGHTS, + ArrayMesh::ARRAY_INDEX }; /* compatibility */ static const int _format_translate[] = { - Mesh::ARRAY_FORMAT_VERTEX, - Mesh::ARRAY_FORMAT_NORMAL, - Mesh::ARRAY_FORMAT_TANGENT, - Mesh::ARRAY_FORMAT_COLOR, - Mesh::ARRAY_FORMAT_TEX_UV, - Mesh::ARRAY_FORMAT_TEX_UV2, - Mesh::ARRAY_FORMAT_BONES, - Mesh::ARRAY_FORMAT_WEIGHTS, - Mesh::ARRAY_FORMAT_INDEX, + ArrayMesh::ARRAY_FORMAT_VERTEX, + ArrayMesh::ARRAY_FORMAT_NORMAL, + ArrayMesh::ARRAY_FORMAT_TANGENT, + ArrayMesh::ARRAY_FORMAT_COLOR, + ArrayMesh::ARRAY_FORMAT_TEX_UV, + ArrayMesh::ARRAY_FORMAT_TEX_UV2, + ArrayMesh::ARRAY_FORMAT_BONES, + ArrayMesh::ARRAY_FORMAT_WEIGHTS, + ArrayMesh::ARRAY_FORMAT_INDEX, }; -bool Mesh::_set(const StringName &p_name, const Variant &p_value) { +bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { String sname = p_name; @@ -191,7 +575,7 @@ bool Mesh::_set(const StringName &p_name, const Variant &p_value) { return false; } -bool Mesh::_get(const StringName &p_name, Variant &r_ret) const { +bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { if (_is_generated()) return false; @@ -270,7 +654,7 @@ bool Mesh::_get(const StringName &p_name, Variant &r_ret) const { return true; } -void Mesh::_get_property_list(List<PropertyInfo> *p_list) const { +void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const { if (_is_generated()) return; @@ -290,7 +674,7 @@ void Mesh::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::RECT3, "custom_aabb/custom_aabb")); } -void Mesh::_recompute_aabb() { +void ArrayMesh::_recompute_aabb() { // regenerate AABB aabb = Rect3(); @@ -304,16 +688,17 @@ void Mesh::_recompute_aabb() { } } -void Mesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<Rect3> &p_bone_aabbs) { +void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<Rect3> &p_bone_aabbs) { Surface s; s.aabb = p_aabb; surfaces.push_back(s); + _recompute_aabb(); 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) { +void ArrayMesh::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); @@ -345,28 +730,28 @@ void Mesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arr _recompute_aabb(); } - triangle_mesh = Ref<TriangleMesh>(); + _clear_triangle_mesh(); _change_notify(); emit_changed(); } -Array Mesh::surface_get_arrays(int p_surface) const { +Array ArrayMesh::surface_get_arrays(int p_surface) const { ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array()); return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, p_surface); } -Array Mesh::surface_get_blend_shape_arrays(int p_surface) const { +Array ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const { ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array()); return Array(); } -int Mesh::get_surface_count() const { +int ArrayMesh::get_surface_count() const { return surfaces.size(); } -void Mesh::add_blend_shape(const StringName &p_name) { +void ArrayMesh::add_blend_shape(const StringName &p_name) { if (surfaces.size()) { ERR_EXPLAIN("Can't add a shape key count if surfaces are already created."); @@ -389,15 +774,15 @@ void Mesh::add_blend_shape(const StringName &p_name) { VS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); } -int Mesh::get_blend_shape_count() const { +int ArrayMesh::get_blend_shape_count() const { return blend_shapes.size(); } -StringName Mesh::get_blend_shape_name(int p_index) const { +StringName ArrayMesh::get_blend_shape_name(int p_index) const { ERR_FAIL_INDEX_V(p_index, blend_shapes.size(), StringName()); return blend_shapes[p_index]; } -void Mesh::clear_blend_shapes() { +void ArrayMesh::clear_blend_shapes() { if (surfaces.size()) { ERR_EXPLAIN("Can't set shape key count if surfaces are already created."); @@ -407,54 +792,54 @@ void Mesh::clear_blend_shapes() { blend_shapes.clear(); } -void Mesh::set_blend_shape_mode(BlendShapeMode p_mode) { +void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) { blend_shape_mode = p_mode; VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)p_mode); } -Mesh::BlendShapeMode Mesh::get_blend_shape_mode() const { +ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const { return blend_shape_mode; } -void Mesh::surface_remove(int p_idx) { +void ArrayMesh::surface_remove(int p_idx) { ERR_FAIL_INDEX(p_idx, surfaces.size()); VisualServer::get_singleton()->mesh_remove_surface(mesh, p_idx); surfaces.remove(p_idx); - triangle_mesh = Ref<TriangleMesh>(); + _clear_triangle_mesh(); _recompute_aabb(); _change_notify(); emit_changed(); } -int Mesh::surface_get_array_len(int p_idx) const { +int ArrayMesh::surface_get_array_len(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1); return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, p_idx); } -int Mesh::surface_get_array_index_len(int p_idx) const { +int ArrayMesh::surface_get_array_index_len(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1); return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, p_idx); } -uint32_t Mesh::surface_get_format(int p_idx) const { +uint32_t ArrayMesh::surface_get_format(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), 0); return VisualServer::get_singleton()->mesh_surface_get_format(mesh, p_idx); } -Mesh::PrimitiveType Mesh::surface_get_primitive_type(int p_idx) const { +ArrayMesh::PrimitiveType ArrayMesh::surface_get_primitive_type(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), PRIMITIVE_LINES); return (PrimitiveType)VisualServer::get_singleton()->mesh_surface_get_primitive_type(mesh, p_idx); } -void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) { +void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) { ERR_FAIL_INDEX(p_idx, surfaces.size()); if (surfaces[p_idx].material == p_material) @@ -465,33 +850,33 @@ void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) { _change_notify("material"); } -void Mesh::surface_set_name(int p_idx, const String &p_name) { +void ArrayMesh::surface_set_name(int p_idx, const String &p_name) { ERR_FAIL_INDEX(p_idx, surfaces.size()); surfaces[p_idx].name = p_name; } -String Mesh::surface_get_name(int p_idx) const { +String ArrayMesh::surface_get_name(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), String()); return surfaces[p_idx].name; } -void Mesh::surface_set_custom_aabb(int p_idx, const Rect3 &p_aabb) { +void ArrayMesh::surface_set_custom_aabb(int p_idx, const Rect3 &p_aabb) { ERR_FAIL_INDEX(p_idx, surfaces.size()); surfaces[p_idx].aabb = p_aabb; // set custom aabb too? } -Ref<Material> Mesh::surface_get_material(int p_idx) const { +Ref<Material> ArrayMesh::surface_get_material(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), Ref<Material>()); return surfaces[p_idx].material; } -void Mesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) { +void ArrayMesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) { VisualServer::get_singleton()->mesh_add_surface_from_mesh_data(mesh, p_mesh_data); Rect3 aabb; @@ -510,7 +895,7 @@ void Mesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) { else aabb.merge_with(s.aabb); - triangle_mesh = Ref<TriangleMesh>(); + _clear_triangle_mesh(); surfaces.push_back(s); _change_notify(); @@ -518,129 +903,27 @@ void Mesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) { emit_changed(); } -RID Mesh::get_rid() const { +RID ArrayMesh::get_rid() const { return mesh; } -Rect3 Mesh::get_aabb() const { +Rect3 ArrayMesh::get_aabb() const { return aabb; } -void Mesh::set_custom_aabb(const Rect3 &p_custom) { +void ArrayMesh::set_custom_aabb(const Rect3 &p_custom) { custom_aabb = p_custom; VS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb); } -Rect3 Mesh::get_custom_aabb() const { +Rect3 ArrayMesh::get_custom_aabb() const { return custom_aabb; } -PoolVector<Face3> Mesh::get_faces() const { - - Ref<TriangleMesh> tm = generate_triangle_mesh(); - if (tm.is_valid()) - return tm->get_faces(); - return PoolVector<Face3>(); - /* - for (int i=0;i<surfaces.size();i++) { - - if (VisualServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != VisualServer::PRIMITIVE_TRIANGLES ) - continue; - - PoolVector<int> indices; - PoolVector<Vector3> vertices; - - vertices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_VERTEX); - - int len=VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, i); - bool has_indices; - - if (len>0) { - - indices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_INDEX); - has_indices=true; - - } else { - - len=vertices.size(); - has_indices=false; - } - - if (len<=0) - continue; - - PoolVector<int>::Read indicesr = indices.read(); - const int *indicesptr = indicesr.ptr(); - - PoolVector<Vector3>::Read verticesr = vertices.read(); - const Vector3 *verticesptr = verticesr.ptr(); - - int old_faces=faces.size(); - int new_faces=old_faces+(len/3); - - faces.resize(new_faces); - - PoolVector<Face3>::Write facesw = faces.write(); - Face3 *facesptr=facesw.ptr(); - - - for (int i=0;i<len/3;i++) { - - Face3 face; - - for (int j=0;j<3;j++) { - - int idx=i*3+j; - face.vertex[j] = has_indices ? verticesptr[ indicesptr[ idx ] ] : verticesptr[idx]; - } - - facesptr[i+old_faces]=face; - } - - } -*/ -} - -Ref<Shape> Mesh::create_convex_shape() const { - - PoolVector<Vector3> vertices; - - for (int i = 0; i < get_surface_count(); i++) { - - Array a = surface_get_arrays(i); - PoolVector<Vector3> v = a[ARRAY_VERTEX]; - vertices.append_array(v); - } - - Ref<ConvexPolygonShape> shape = memnew(ConvexPolygonShape); - shape->set_points(vertices); - return shape; -} - -Ref<Shape> Mesh::create_trimesh_shape() const { - - PoolVector<Face3> faces = get_faces(); - if (faces.size() == 0) - return Ref<Shape>(); - - PoolVector<Vector3> face_points; - face_points.resize(faces.size() * 3); - - for (int i = 0; i < face_points.size(); i++) { - - Face3 f = faces.get(i / 3); - face_points.set(i, f.vertex[i % 3]); - } - - Ref<ConcavePolygonShape> shape = memnew(ConcavePolygonShape); - shape->set_faces(face_points); - return shape; -} - -void Mesh::center_geometry() { +void ArrayMesh::center_geometry() { /* Vector3 ofs = aabb.pos+aabb.size*0.5; @@ -668,13 +951,13 @@ void Mesh::center_geometry() { */ } -void Mesh::regen_normalmaps() { +void ArrayMesh::regen_normalmaps() { Vector<Ref<SurfaceTool> > surfs; for (int i = 0; i < get_surface_count(); i++) { Ref<SurfaceTool> st = memnew(SurfaceTool); - st->create_from(Ref<Mesh>(this), i); + st->create_from(Ref<ArrayMesh>(this), i); surfs.push_back(st); } @@ -685,315 +968,42 @@ void Mesh::regen_normalmaps() { for (int i = 0; i < surfs.size(); i++) { surfs[i]->generate_tangents(); - surfs[i]->commit(Ref<Mesh>(this)); - } -} - -Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { - - if (triangle_mesh.is_valid()) - return triangle_mesh; - - int facecount = 0; - - for (int i = 0; i < get_surface_count(); i++) { - - if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) - continue; - - if (surface_get_format(i) & ARRAY_FORMAT_INDEX) { - - facecount += surface_get_array_index_len(i); - } else { - - facecount += surface_get_array_len(i); - } - } - - if (facecount == 0 || (facecount % 3) != 0) - return triangle_mesh; - - PoolVector<Vector3> faces; - faces.resize(facecount); - PoolVector<Vector3>::Write facesw = faces.write(); - - int widx = 0; - - for (int i = 0; i < get_surface_count(); i++) { - - if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) - continue; - - Array a = surface_get_arrays(i); - - int vc = surface_get_array_len(i); - PoolVector<Vector3> vertices = a[ARRAY_VERTEX]; - PoolVector<Vector3>::Read vr = vertices.read(); - - if (surface_get_format(i) & ARRAY_FORMAT_INDEX) { - - int ic = surface_get_array_index_len(i); - PoolVector<int> indices = a[ARRAY_INDEX]; - PoolVector<int>::Read ir = indices.read(); - - for (int i = 0; i < ic; i++) { - int index = ir[i]; - facesw[widx++] = vr[index]; - } - - } else { - - for (int i = 0; i < vc; i++) - facesw[widx++] = vr[i]; - } + surfs[i]->commit(Ref<ArrayMesh>(this)); } - - facesw = PoolVector<Vector3>::Write(); - - triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); - triangle_mesh->create(faces); - - return triangle_mesh; } -Ref<Mesh> Mesh::create_outline(float p_margin) const { - - Array arrays; - int index_accum = 0; - for (int i = 0; i < get_surface_count(); i++) { - - if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) - continue; - - Array a = surface_get_arrays(i); - int vcount = 0; - - if (i == 0) { - arrays = a; - PoolVector<Vector3> v = a[ARRAY_VERTEX]; - index_accum += v.size(); - } else { - - for (int j = 0; j < arrays.size(); j++) { - - if (arrays[j].get_type() == Variant::NIL || a[j].get_type() == Variant::NIL) { - //mismatch, do not use - arrays[j] = Variant(); - continue; - } - - switch (j) { - - case ARRAY_VERTEX: - case ARRAY_NORMAL: { - - PoolVector<Vector3> dst = arrays[j]; - PoolVector<Vector3> src = a[j]; - if (j == ARRAY_VERTEX) - vcount = src.size(); - if (dst.size() == 0 || src.size() == 0) { - arrays[j] = Variant(); - continue; - } - dst.append_array(src); - arrays[j] = dst; - } break; - case ARRAY_TANGENT: - case ARRAY_BONES: - case ARRAY_WEIGHTS: { - - PoolVector<real_t> dst = arrays[j]; - PoolVector<real_t> src = a[j]; - if (dst.size() == 0 || src.size() == 0) { - arrays[j] = Variant(); - continue; - } - dst.append_array(src); - arrays[j] = dst; - - } break; - case ARRAY_COLOR: { - PoolVector<Color> dst = arrays[j]; - PoolVector<Color> src = a[j]; - if (dst.size() == 0 || src.size() == 0) { - arrays[j] = Variant(); - continue; - } - dst.append_array(src); - arrays[j] = dst; - - } break; - case ARRAY_TEX_UV: - case ARRAY_TEX_UV2: { - PoolVector<Vector2> dst = arrays[j]; - PoolVector<Vector2> src = a[j]; - if (dst.size() == 0 || src.size() == 0) { - arrays[j] = Variant(); - continue; - } - dst.append_array(src); - arrays[j] = dst; - - } break; - case ARRAY_INDEX: { - PoolVector<int> dst = arrays[j]; - PoolVector<int> src = a[j]; - if (dst.size() == 0 || src.size() == 0) { - arrays[j] = Variant(); - continue; - } - { - int ss = src.size(); - PoolVector<int>::Write w = src.write(); - for (int k = 0; k < ss; k++) { - w[k] += index_accum; - } - } - dst.append_array(src); - arrays[j] = dst; - index_accum += vcount; - - } break; - } - } - } - } - - { - PoolVector<int>::Write ir; - PoolVector<int> indices = arrays[ARRAY_INDEX]; - bool has_indices = false; - PoolVector<Vector3> vertices = arrays[ARRAY_VERTEX]; - int vc = vertices.size(); - ERR_FAIL_COND_V(!vc, Ref<Mesh>()); - PoolVector<Vector3>::Write r = vertices.write(); - - if (indices.size()) { - vc = indices.size(); - ir = indices.write(); - has_indices = true; - } - - Map<Vector3, Vector3> normal_accum; - - //fill normals with triangle normals - for (int i = 0; i < vc; i += 3) { - - Vector3 t[3]; - - if (has_indices) { - t[0] = r[ir[i + 0]]; - t[1] = r[ir[i + 1]]; - t[2] = r[ir[i + 2]]; - } else { - t[0] = r[i + 0]; - t[1] = r[i + 1]; - t[2] = r[i + 2]; - } - - Vector3 n = Plane(t[0], t[1], t[2]).normal; - - for (int j = 0; j < 3; j++) { - - Map<Vector3, Vector3>::Element *E = normal_accum.find(t[j]); - if (!E) { - normal_accum[t[j]] = n; - } else { - float d = n.dot(E->get()); - if (d < 1.0) - E->get() += n * (1.0 - d); - //E->get()+=n; - } - } - } - - //normalize - - for (Map<Vector3, Vector3>::Element *E = normal_accum.front(); E; E = E->next()) { - E->get().normalize(); - } - - //displace normals - int vc2 = vertices.size(); - - for (int i = 0; i < vc2; i++) { - - Vector3 t = r[i]; - - Map<Vector3, Vector3>::Element *E = normal_accum.find(t); - ERR_CONTINUE(!E); - - t += E->get() * p_margin; - r[i] = t; - } - - r = PoolVector<Vector3>::Write(); - arrays[ARRAY_VERTEX] = vertices; - - if (!has_indices) { - - PoolVector<int> new_indices; - new_indices.resize(vertices.size()); - PoolVector<int>::Write iw = new_indices.write(); - - for (int j = 0; j < vc2; j += 3) { - - iw[j] = j; - iw[j + 1] = j + 2; - iw[j + 2] = j + 1; - } - - iw = PoolVector<int>::Write(); - arrays[ARRAY_INDEX] = new_indices; - - } else { - - for (int j = 0; j < vc; j += 3) { - - SWAP(ir[j + 1], ir[j + 2]); - } - ir = PoolVector<int>::Write(); - arrays[ARRAY_INDEX] = indices; - } - } - - Ref<Mesh> newmesh = memnew(Mesh); - newmesh->add_surface_from_arrays(PRIMITIVE_TRIANGLES, arrays); - return newmesh; -} - -void Mesh::_bind_methods() { - - ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &Mesh::add_blend_shape); - ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &Mesh::get_blend_shape_count); - ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &Mesh::get_blend_shape_name); - ClassDB::bind_method(D_METHOD("clear_blend_shapes"), &Mesh::clear_blend_shapes); - ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &Mesh::set_blend_shape_mode); - ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &Mesh::get_blend_shape_mode); - - ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &Mesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); - ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count); - ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &Mesh::surface_remove); - ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &Mesh::surface_get_array_len); - ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &Mesh::surface_get_array_index_len); - ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &Mesh::surface_get_format); - ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &Mesh::surface_get_primitive_type); - ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material:Material"), &Mesh::surface_set_material); - ClassDB::bind_method(D_METHOD("surface_get_material:Material", "surf_idx"), &Mesh::surface_get_material); - ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &Mesh::surface_set_name); - ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &Mesh::surface_get_name); - ClassDB::bind_method(D_METHOD("create_trimesh_shape:Shape"), &Mesh::create_trimesh_shape); - ClassDB::bind_method(D_METHOD("create_convex_shape:Shape"), &Mesh::create_convex_shape); - ClassDB::bind_method(D_METHOD("create_outline:Mesh", "margin"), &Mesh::create_outline); - ClassDB::bind_method(D_METHOD("center_geometry"), &Mesh::center_geometry); +void ArrayMesh::_bind_methods() { + + ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape); + ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count); + ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &ArrayMesh::get_blend_shape_name); + ClassDB::bind_method(D_METHOD("clear_blend_shapes"), &ArrayMesh::clear_blend_shapes); + ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode); + ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode); + + ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); + ClassDB::bind_method(D_METHOD("get_surface_count"), &ArrayMesh::get_surface_count); + ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &ArrayMesh::surface_remove); + ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len); + ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len); + ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format); + ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &ArrayMesh::surface_get_primitive_type); + ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material:Material"), &ArrayMesh::surface_set_material); + ClassDB::bind_method(D_METHOD("surface_get_material:Material", "surf_idx"), &ArrayMesh::surface_get_material); + ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name); + ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name); + ClassDB::bind_method(D_METHOD("create_trimesh_shape:Shape"), &ArrayMesh::create_trimesh_shape); + ClassDB::bind_method(D_METHOD("create_convex_shape:Shape"), &ArrayMesh::create_convex_shape); + ClassDB::bind_method(D_METHOD("create_outline:ArrayMesh", "margin"), &ArrayMesh::create_outline); + ClassDB::bind_method(D_METHOD("center_geometry"), &ArrayMesh::center_geometry); ClassDB::set_method_flags(get_class_static(), _scs_create("center_geometry"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); - ClassDB::bind_method(D_METHOD("regen_normalmaps"), &Mesh::regen_normalmaps); + ClassDB::bind_method(D_METHOD("regen_normalmaps"), &ArrayMesh::regen_normalmaps); ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normalmaps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); - ClassDB::bind_method(D_METHOD("get_faces"), &Mesh::get_faces); - ClassDB::bind_method(D_METHOD("generate_triangle_mesh:TriangleMesh"), &Mesh::generate_triangle_mesh); + ClassDB::bind_method(D_METHOD("get_faces"), &ArrayMesh::get_faces); + ClassDB::bind_method(D_METHOD("generate_triangle_mesh:TriangleMesh"), &ArrayMesh::generate_triangle_mesh); - ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &Mesh::set_custom_aabb); - ClassDB::bind_method(D_METHOD("get_custom_aabb"), &Mesh::get_custom_aabb); + ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb); + ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb); BIND_CONSTANT(NO_INDEX_ARRAY); BIND_CONSTANT(ARRAY_WEIGHTS_SIZE); @@ -1027,19 +1037,19 @@ void Mesh::_bind_methods() { BIND_CONSTANT(PRIMITIVE_TRIANGLE_FAN); } -Mesh::Mesh() { +ArrayMesh::ArrayMesh() { mesh = VisualServer::get_singleton()->mesh_create(); blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE; } -Mesh::~Mesh() { +ArrayMesh::~ArrayMesh() { VisualServer::get_singleton()->free(mesh); } //////////////////////// - +#if 0 void QuadMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &QuadMesh::set_material); @@ -1105,3 +1115,4 @@ QuadMesh::QuadMesh() { add_surface_from_arrays(PRIMITIVE_TRIANGLE_FAN, arr); } +#endif diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index e441b4924a..7804a84f81 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -38,10 +38,13 @@ /** @author Juan Linietsky <reduzio@gmail.com> */ -class Mesh : public Resource { +class Mesh : public Resource { GDCLASS(Mesh, Resource); - RES_BASE_EXTENSION("msh"); + + mutable Ref<TriangleMesh> triangle_mesh; //cached +protected: + void _clear_triangle_mesh(); public: enum { @@ -111,6 +114,34 @@ public: BLEND_SHAPE_MODE_RELATIVE = VS::BLEND_SHAPE_MODE_RELATIVE, }; + virtual int get_surface_count() const = 0; + virtual int surface_get_array_len(int p_idx) const = 0; + virtual int surface_get_array_index_len(int p_idx) const = 0; + virtual Array surface_get_arrays(int p_surface) const = 0; + virtual uint32_t surface_get_format(int p_idx) const = 0; + virtual PrimitiveType surface_get_primitive_type(int p_idx) const = 0; + virtual Ref<Material> surface_get_material(int p_idx) const = 0; + virtual int get_blend_shape_count() const = 0; + virtual StringName get_blend_shape_name(int p_index) const = 0; + + PoolVector<Face3> get_faces() const; + Ref<TriangleMesh> generate_triangle_mesh() const; + + Ref<Shape> create_trimesh_shape() const; + Ref<Shape> create_convex_shape() const; + + Ref<Mesh> create_outline(float p_margin) const; + + virtual Rect3 get_aabb() const = 0; + + Mesh(); +}; + +class ArrayMesh : public Mesh { + + GDCLASS(ArrayMesh, Mesh); + RES_BASE_EXTENSION("msh"); + private: struct Surface { String name; @@ -124,8 +155,6 @@ private: Vector<StringName> blend_shapes; Rect3 custom_aabb; - mutable Ref<TriangleMesh> triangle_mesh; - void _recompute_aabb(); protected: @@ -177,21 +206,15 @@ public: Rect3 get_aabb() const; virtual RID get_rid() const; - Ref<Shape> create_trimesh_shape() const; - Ref<Shape> create_convex_shape() const; - - Ref<Mesh> create_outline(float p_margin) const; - void center_geometry(); void regen_normalmaps(); - PoolVector<Face3> get_faces() const; - Ref<TriangleMesh> generate_triangle_mesh() const; - Mesh(); + ArrayMesh(); - ~Mesh(); + ~ArrayMesh(); }; +#if 0 class QuadMesh : public Mesh { GDCLASS(QuadMesh, Mesh) @@ -206,6 +229,8 @@ public: QuadMesh(); }; +#endif + VARIANT_ENUM_CAST(Mesh::ArrayType); VARIANT_ENUM_CAST(Mesh::PrimitiveType); VARIANT_ENUM_CAST(Mesh::BlendShapeMode); diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index b6b47bf443..dc3713fb57 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -38,7 +38,7 @@ void MeshDataTool::clear() { format = 0; } -Error MeshDataTool::create_from_surface(const Ref<Mesh> &p_mesh, int p_surface) { +Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surface) { ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER); @@ -179,7 +179,7 @@ Error MeshDataTool::create_from_surface(const Ref<Mesh> &p_mesh, int p_surface) return OK; } -Error MeshDataTool::commit_to_surface(const Ref<Mesh> &p_mesh) { +Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) { ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER); Array arr; @@ -309,7 +309,7 @@ Error MeshDataTool::commit_to_surface(const Ref<Mesh> &p_mesh) { if (w.size()) arr[Mesh::ARRAY_WEIGHTS] = w; - Ref<Mesh> ncmesh = p_mesh; + Ref<ArrayMesh> ncmesh = p_mesh; int sc = ncmesh->get_surface_count(); ncmesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr); ncmesh->surface_set_material(sc, material); diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h index f6797d3e5e..ad771edbd1 100644 --- a/scene/resources/mesh_data_tool.h +++ b/scene/resources/mesh_data_tool.h @@ -78,8 +78,8 @@ protected: public: void clear(); - Error create_from_surface(const Ref<Mesh> &p_mesh, int p_surface); - Error commit_to_surface(const Ref<Mesh> &p_mesh); + Error create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surface); + Error commit_to_surface(const Ref<ArrayMesh> &p_mesh); int get_format() const; diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp index b449932b17..77f2096d9b 100644 --- a/scene/resources/shape.cpp +++ b/scene/resources/shape.cpp @@ -49,14 +49,14 @@ void Shape::add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p } } -Ref<Mesh> Shape::get_debug_mesh() { +Ref<ArrayMesh> Shape::get_debug_mesh() { if (debug_mesh_cache.is_valid()) return debug_mesh_cache; Vector<Vector3> lines = _gen_debug_mesh_lines(); - debug_mesh_cache = Ref<Mesh>(memnew(Mesh)); + debug_mesh_cache = Ref<ArrayMesh>(memnew(ArrayMesh)); if (!lines.empty()) { //make mesh diff --git a/scene/resources/shape.h b/scene/resources/shape.h index 01b8db650e..ea3ba9ab0a 100644 --- a/scene/resources/shape.h +++ b/scene/resources/shape.h @@ -31,7 +31,7 @@ #define SHAPE_H #include "resource.h" -class Mesh; +class ArrayMesh; class Shape : public Resource { @@ -40,7 +40,7 @@ class Shape : public Resource { RES_BASE_EXTENSION("shp"); RID shape; - Ref<Mesh> debug_mesh_cache; + Ref<ArrayMesh> debug_mesh_cache; protected: _FORCE_INLINE_ RID get_shape() const { return shape; } @@ -50,7 +50,7 @@ protected: public: virtual RID get_rid() const { return shape; } - Ref<Mesh> get_debug_mesh(); + Ref<ArrayMesh> get_debug_mesh(); void add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform); diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 4c36d79a7a..60fb97c792 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -224,13 +224,13 @@ void SurfaceTool::add_index(int p_index) { index_array.push_back(p_index); } -Ref<Mesh> SurfaceTool::commit(const Ref<Mesh> &p_existing) { +Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) { - Ref<Mesh> mesh; + Ref<ArrayMesh> mesh; if (p_existing.is_valid()) mesh = p_existing; else - mesh = Ref<Mesh>(memnew(Mesh)); + mesh.instance(); int varr_len = vertex_array.size(); diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index b143086e11..753c3626b8 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -125,7 +125,7 @@ public: void create_from(const Ref<Mesh> &p_existing, int p_surface); void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform); - Ref<Mesh> commit(const Ref<Mesh> &p_existing = Ref<Mesh>()); + Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>()); SurfaceTool(); }; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index a1e0c95dd9..0b8ad5536c 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -1781,6 +1781,10 @@ float GradientTexture::get_offset(int pos) const { return 0; //TODO: Maybe throw some error instead? } +Ref<Image> GradientTexture::get_data() const { + return VisualServer::get_singleton()->texture_get_data(texture); +} + void GradientTexture::set_color(int pos, const Color &color) { if (points.size() <= pos) { points.resize(pos + 1); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 07416529ae..9ee9588d2b 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -539,6 +539,8 @@ public: return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset)); } + virtual Ref<Image> get_data() const; + int get_points_count() const; GradientTexture(); |