summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/variant_parser.cpp8
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp61
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h52
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp1
-rw-r--r--drivers/gles3/shaders/scene.glsl70
-rw-r--r--editor/editor_help.cpp7
-rw-r--r--editor/editor_node.cpp1
-rw-r--r--editor/editor_themes.cpp13
-rw-r--r--editor/import/editor_import_collada.cpp16
-rw-r--r--editor/import/resource_importer_obj.cpp2
-rw-r--r--editor/import/resource_importer_scene.cpp26
-rw-r--r--editor/import/resource_importer_scene.h5
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp4
-rw-r--r--editor/plugins/spatial_editor_plugin.h8
-rw-r--r--editor/spatial_editor_gizmos.cpp18
-rw-r--r--editor/spatial_editor_gizmos.h8
-rw-r--r--modules/hdr/image_loader_hdr.h4
-rw-r--r--modules/tga/SCsub9
-rw-r--r--modules/tga/config.py7
-rw-r--r--modules/tga/image_loader_tga.cpp314
-rw-r--r--modules/tga/image_loader_tga.h83
-rw-r--r--modules/tga/register_types.cpp45
-rw-r--r--modules/tga/register_types.h31
-rw-r--r--platform/android/java_glue.cpp2
-rw-r--r--platform/android/os_android.cpp16
-rw-r--r--platform/osx/os_osx.mm2
-rw-r--r--scene/3d/gi_probe.cpp8
-rw-r--r--scene/3d/gi_probe.h4
-rw-r--r--scene/3d/listener.cpp2
-rw-r--r--scene/3d/navigation_mesh.cpp2
-rw-r--r--scene/3d/navigation_mesh.h2
-rw-r--r--scene/3d/ray_cast.cpp4
-rw-r--r--scene/gui/rich_text_label.cpp2
-rw-r--r--scene/main/scene_main_loop.cpp4
-rw-r--r--scene/main/scene_main_loop.h5
-rw-r--r--scene/register_scene_types.cpp5
-rw-r--r--scene/resources/environment.cpp239
-rw-r--r--scene/resources/environment.h56
-rw-r--r--scene/resources/mesh.cpp938
-rw-r--r--scene/resources/mesh.h51
-rw-r--r--scene/resources/mesh_data_tool.cpp6
-rw-r--r--scene/resources/mesh_data_tool.h4
-rw-r--r--scene/resources/shape.cpp4
-rw-r--r--scene/resources/shape.h6
-rw-r--r--scene/resources/surface_tool.cpp6
-rw-r--r--scene/resources/surface_tool.h2
-rw-r--r--servers/visual/rasterizer.h4
-rw-r--r--servers/visual/shader_types.cpp1
-rw-r--r--servers/visual/visual_server_raster.h4
-rw-r--r--servers/visual_server.h4
50 files changed, 1601 insertions, 575 deletions
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 0553ba4319..da78d98134 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -744,7 +744,12 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return err;
if (token.type == TK_PARENTHESIS_CLOSE) {
-
+ Reference *reference = obj->cast_to<Reference>();
+ if (reference) {
+ value = REF(reference);
+ } else {
+ value = obj;
+ }
return OK;
}
@@ -760,7 +765,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
}
- get_token(p_stream, token, line, r_err_str);
if (token.type != TK_STRING) {
r_err_str = "Expected property name as string";
return ERR_PARSE_ERROR;
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index de79c034cb..af03819a16 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -944,6 +944,40 @@ void RasterizerSceneGLES3::environment_set_adjustment(RID p_env, bool p_enable,
env->color_correction = p_ramp;
}
+void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_enabled = p_enable;
+ env->fog_color = p_color;
+ env->fog_sun_color = p_sun_color;
+ env->fog_sun_amount = p_sun_amount;
+}
+
+void RasterizerSceneGLES3::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_depth_enabled = p_enable;
+ env->fog_depth_begin = p_depth_begin;
+ env->fog_depth_curve = p_depth_curve;
+ env->fog_transmit_enabled = p_transmit;
+ env->fog_transmit_curve = p_transmit_curve;
+}
+
+void RasterizerSceneGLES3::environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_height_enabled = p_enable;
+ env->fog_height_min = p_min_height;
+ env->fog_height_max = p_max_height;
+ env->fog_height_curve = p_height_curve;
+}
+
RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
LightInstance *light_instance = memnew(LightInstance);
@@ -2224,6 +2258,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.ubo_data.time[i] = storage->frame.time[i];
}
+ state.ubo_data.z_far = p_cam_projection.get_z_far();
//bg and ambient
if (env) {
state.ubo_data.bg_energy = env->bg_energy;
@@ -2255,6 +2290,30 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.env_radiance_data.ambient_contribution = env->ambient_sky_contribution;
state.ubo_data.ambient_occlusion_affect_light = env->ssao_light_affect;
+
+ //fog
+
+ Color linear_fog = env->fog_color.to_linear();
+ state.ubo_data.fog_color_enabled[0] = linear_fog.r;
+ state.ubo_data.fog_color_enabled[1] = linear_fog.g;
+ state.ubo_data.fog_color_enabled[2] = linear_fog.b;
+ state.ubo_data.fog_color_enabled[3] = env->fog_enabled ? 1.0 : 0.0;
+
+ Color linear_sun = env->fog_sun_color.to_linear();
+ state.ubo_data.fog_sun_color_amount[0] = linear_sun.r;
+ state.ubo_data.fog_sun_color_amount[1] = linear_sun.g;
+ state.ubo_data.fog_sun_color_amount[2] = linear_sun.b;
+ state.ubo_data.fog_sun_color_amount[3] = env->fog_sun_amount;
+ state.ubo_data.fog_depth_enabled = env->fog_depth_enabled;
+ state.ubo_data.fog_depth_begin = env->fog_depth_begin;
+ state.ubo_data.fog_depth_curve = env->fog_depth_curve;
+ state.ubo_data.fog_transmit_enabled = env->fog_transmit_enabled;
+ state.ubo_data.fog_transmit_curve = env->fog_transmit_curve;
+ state.ubo_data.fog_height_enabled = env->fog_height_enabled;
+ state.ubo_data.fog_height_min = env->fog_height_min;
+ state.ubo_data.fog_height_max = env->fog_height_max;
+ state.ubo_data.fog_height_curve = env->fog_height_curve;
+
} else {
state.ubo_data.bg_energy = 1.0;
state.ubo_data.ambient_energy = 1.0;
@@ -2272,6 +2331,8 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.env_radiance_data.ambient_contribution = 0;
state.ubo_data.ambient_occlusion_affect_light = 0;
+
+ state.ubo_data.fog_color_enabled[3] = 0.0;
}
{
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 03c6f080ac..55d314a800 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -111,6 +111,9 @@ public:
float time[4];
float ambient_light_color[4];
float bg_color[4];
+ float fog_color_enabled[4];
+ float fog_sun_color_amount[4];
+
float ambient_energy;
float bg_energy;
float shadow_z_offset;
@@ -120,10 +123,22 @@ public:
float screen_pixel_size[2];
float shadow_atlas_pixel_size[2];
float shadow_directional_pixel_size[2];
+
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ 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;
+
} ubo_data;
GLuint scene_ubo;
@@ -396,6 +411,21 @@ public:
float adjustments_saturation;
RID color_correction;
+ 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;
+
Environment() {
bg_mode = VS::ENV_BG_CLEAR_COLOR;
sky_scale = 1.0;
@@ -457,6 +487,24 @@ public:
adjustments_brightness = 1.0;
adjustments_contrast = 1.0;
adjustments_saturation = 1.0;
+
+ 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 = true;
+ fog_transmit_curve = 1;
+
+ fog_height_enabled = false;
+ fog_height_min = 0;
+ fog_height_max = 100;
+ fog_height_curve = 1;
}
};
@@ -484,6 +532,10 @@ public:
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp);
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount);
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve);
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve);
+
/* LIGHT INSTANCE */
struct LightDataUBO {
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 4f741c6b7a..b1f7b4c9bd 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -747,6 +747,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom";
actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv";
actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
+ actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer";
actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side";
actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index f498eae9f5..8965f475d7 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -67,6 +67,10 @@ layout(std140) uniform SceneData { //ubo:0
highp vec4 ambient_light_color;
highp vec4 bg_color;
+
+ vec4 fog_color_enabled;
+ vec4 fog_sun_color_amount;
+
float ambient_energy;
float bg_energy;
@@ -79,10 +83,21 @@ layout(std140) uniform SceneData { //ubo:0
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ 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;
+
};
uniform highp mat4 world_transform;
@@ -425,6 +440,8 @@ layout(std140) uniform SceneData {
highp vec4 ambient_light_color;
highp vec4 bg_color;
+ vec4 fog_color_enabled;
+ vec4 fog_sun_color_amount;
float ambient_energy;
float bg_energy;
@@ -438,10 +455,20 @@ layout(std140) uniform SceneData {
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ 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;
};
//directional light data
@@ -1615,6 +1642,49 @@ FRAGMENT_SHADER_CODE
specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0;
}
+ if (fog_color_enabled.a > 0.5) {
+
+ float fog_amount=0;
+
+
+
+#ifdef USE_LIGHT_DIRECTIONAL
+
+ vec3 fog_color = mix( fog_color_enabled.rgb, fog_sun_color_amount.rgb,fog_sun_color_amount.a * pow(max( dot(normalize(vertex),-light_direction_attenuation.xyz), 0.0),8.0) );
+#else
+
+ vec3 fog_color = fog_color_enabled.rgb;
+#endif
+
+ //apply fog
+
+ if (fog_depth_enabled) {
+
+ float fog_z = smoothstep(fog_depth_begin,z_far,-vertex.z);
+
+ fog_amount = pow(fog_z,fog_depth_curve);
+ if (fog_transmit_enabled) {
+ vec3 total_light = emission + ambient_light + specular_light + diffuse_light;
+ float transmit = pow(fog_z,fog_transmit_curve);
+ fog_color = mix(max(total_light,fog_color),fog_color,transmit);
+ }
+ }
+
+ if (fog_height_enabled) {
+ float y = (camera_matrix * vec4(vertex,1.0)).y;
+ fog_amount = max(fog_amount,pow(1.0-smoothstep(fog_height_min,fog_height_max,y),fog_height_curve));
+ }
+
+ float rev_amount = 1.0 - fog_amount;
+
+
+ emission = emission * rev_amount + fog_color * fog_amount;
+ ambient_light*=rev_amount;
+ specular_light*rev_amount;
+ diffuse_light*=rev_amount;
+
+ }
+
#ifdef USE_MULTIPLE_RENDER_TARGETS
#if defined(ENABLE_AO)
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 7fe483c834..11cb61370d 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -252,8 +252,8 @@ void EditorHelpSearch::_confirmed() {
return;
String mdata = ti->get_metadata(0);
+ EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
emit_signal("go_to_help", mdata);
- EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT); // in case EditorHelpSearch beeen invoked on top of other editor window
// go to that
hide();
}
@@ -361,8 +361,8 @@ void EditorHelpIndex::_tree_item_selected() {
if (!s)
return;
+ EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
emit_signal("open_class", s->get_text(0));
- EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT);
hide();
//_goto_desc(s->get_text(0));
@@ -374,7 +374,6 @@ void EditorHelpIndex::select_class(const String &p_class) {
return;
tree_item_map[p_class]->select(0);
class_list->ensure_cursor_is_visible();
- EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT); // in case EditorHelpIndex beeen invoked on top of other editor window
}
void EditorHelpIndex::popup() {
@@ -1279,7 +1278,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
void EditorHelp::_request_help(const String &p_string) {
Error err = _goto_desc(p_string);
if (err == OK) {
- EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT);
+ EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
}
//100 palabras
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index d139cd0d66..0ba6003bee 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1085,6 +1085,7 @@ void EditorNode::_dialog_action(String p_file) {
GlobalConfig::get_singleton()->set("application/main_scene", p_file);
GlobalConfig::get_singleton()->save();
//would be nice to show the project manager opened with the highlighted field..
+ _run(false, ""); // automatically run the project
} break;
case FILE_SAVE_OPTIMIZED: {
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 6f4e32a500..b6952c3024 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -145,8 +145,8 @@ Ref<Theme> create_editor_theme() {
theme->set_icon("unchecked", "PopupMenu", theme->get_icon("Unchecked", "EditorIcons"));
// Editor background
- Ref<StyleBoxFlat> style_background = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
- theme->set_stylebox("Background", "EditorStyles", style_background);
+ Ref<StyleBoxFlat> style_panel = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
+ theme->set_stylebox("Background", "EditorStyles", style_panel);
// Focus
Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(light_color_1, 4, 4, 4, 4);
@@ -193,9 +193,9 @@ Ref<Theme> create_editor_theme() {
theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border);
// Content of each tab
- Ref<StyleBoxFlat> style_panel = make_flat_stylebox(base_color, 1, 4, 1, 1);
- theme->set_stylebox("panel", "TabContainer", style_panel);
- theme->set_stylebox("Content", "EditorStyles", style_panel);
+ Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 1, 4, 1, 1);
+ theme->set_stylebox("panel", "TabContainer", style_content_panel);
+ theme->set_stylebox("Content", "EditorStyles", style_content_panel);
// Button
Ref<StyleBoxFlat> style_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
@@ -395,6 +395,9 @@ Ref<Theme> create_editor_theme() {
theme->set_icon("grabber", "VSlider", theme->get_icon("SliderGrabber", "EditorIcons"));
theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("SliderGrabberHl", "EditorIcons"));
+ // Panel
+ theme->set_stylebox("panel", "Panel", style_panel);
+
// TooltipPanel
Ref<StyleBoxFlat> style_tooltip = make_flat_stylebox(Color(1, 1, 1, 0.8), 8, 8, 8, 8);
style_tooltip->set_border_size(2 * EDSCALE);
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 907c7b045c..e0a2ea624e 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -72,7 +72,7 @@ struct ColladaImport {
Map<String, NodeMap> node_map; //map from collada node to engine node
Map<String, String> node_name_map; //map from collada node to engine node
- Map<String, Ref<Mesh> > mesh_cache;
+ Map<String, Ref<ArrayMesh> > mesh_cache;
Map<String, Ref<Curve3D> > curve_cache;
Map<String, Ref<Material> > material_cache;
Map<Collada::Node *, Skeleton *> skeleton_map;
@@ -88,7 +88,7 @@ struct ColladaImport {
Error _create_scene(Collada::Node *p_node, Spatial *p_parent);
Error _create_resources(Collada::Node *p_node);
Error _create_material(const String &p_material);
- Error _create_mesh_surfaces(bool p_optimize, Ref<Mesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data, Vector<Ref<Mesh> > p_morph_meshes = Vector<Ref<Mesh> >(), bool p_for_morph = false, bool p_use_mesh_material = false);
+ Error _create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh> > p_morph_meshes = Vector<Ref<ArrayMesh> >(), bool p_for_morph = false, bool p_use_mesh_material = false);
Error load(const String &p_path, int p_flags, bool p_force_make_tangents = false);
void _fix_param_animation_tracks();
void create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks);
@@ -591,7 +591,7 @@ static void _generate_tangents_and_binormals(const PoolVector<int> &p_indices, c
}
}
-Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<Mesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<Mesh> > p_morph_meshes, bool p_for_morph, bool p_use_mesh_material) {
+Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh> > p_morph_meshes, bool p_for_morph, bool p_use_mesh_material) {
bool local_xform_mirror = p_local_xform.basis.determinant() < 0;
@@ -1530,7 +1530,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
String meshid;
Transform apply_xform;
Vector<int> bone_remap;
- Vector<Ref<Mesh> > morphs;
+ Vector<Ref<ArrayMesh> > morphs;
print_line("mesh: " + String(mi->get_name()));
@@ -1621,9 +1621,9 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
String meshid = names[i];
if (collada.state.mesh_data_map.has(meshid)) {
- Ref<Mesh> mesh = Ref<Mesh>(memnew(Mesh));
+ Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
- Error err = _create_mesh_surfaces(false, mesh, ng->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<Mesh> >(), true);
+ Error err = _create_mesh_surfaces(false, mesh, ng->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), true);
ERR_FAIL_COND_V(err, err);
morphs.push_back(mesh);
@@ -1648,7 +1648,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
meshid = ng->source;
}
- Ref<Mesh> mesh;
+ Ref<ArrayMesh> mesh;
if (mesh_cache.has(meshid)) {
mesh = mesh_cache[meshid];
} else {
@@ -1656,7 +1656,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
//bleh, must ignore invalid
ERR_FAIL_COND_V(!collada.state.mesh_data_map.has(meshid), ERR_INVALID_DATA);
- mesh = Ref<Mesh>(memnew(Mesh));
+ mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
mesh->set_name(meshdata.name);
Error err = _create_mesh_surfaces(morphs.size() == 0, mesh, ng->material_map, meshdata, apply_xform, bone_remap, skin, morph, morphs, false, use_mesh_builtin_materials);
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index 21c2ae6eb3..8d0f3267f7 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -89,7 +89,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
FileAccessRef f = FileAccess::open(p_source_file, FileAccess::READ);
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
- Ref<Mesh> mesh = Ref<Mesh>(memnew(Mesh));
+ Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
Map<String, Ref<Material> > name_map;
bool generate_normals = p_options["generate/normals"];
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 755f4eb219..d2d2d45a47 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -137,7 +137,7 @@ static String _fixstr(const String &p_what, const String &p_str) {
return p_what;
}
-Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, Ref<Shape> > &collision_map) {
+Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map) {
// children first..
for (int i = 0; i < p_node->get_child_count(); i++) {
@@ -175,7 +175,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
mi->set_flag(GeometryInstance::FLAG_BILLBOARD, true);
if (mi->get_mesh().is_valid()) {
- Ref<Mesh> m = mi->get_mesh();
+ Ref<ArrayMesh> m = mi->get_mesh();
for (int i = 0; i < m->get_surface_count(); i++) {
Ref<SpatialMaterial> fm = m->surface_get_material(i);
@@ -194,7 +194,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
MeshInstance *mi = p_node->cast_to<MeshInstance>();
- Ref<Mesh> m = mi->get_mesh();
+ Ref<ArrayMesh> m = mi->get_mesh();
if (m.is_valid()) {
@@ -275,7 +275,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
if (mi->get_mesh().is_valid()) {
- Ref<Mesh> m = mi->get_mesh();
+ Ref<ArrayMesh> m = mi->get_mesh();
for (int i = 0; i < m->get_surface_count(); i++) {
Ref<SpatialMaterial> fm = m->surface_get_material(i);
@@ -325,7 +325,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
/*if (mi->get_mesh().is_valid()) {
- Ref<Mesh> m = mi->get_mesh();
+ Ref<ArrayMesh> m = mi->get_mesh();
for(int i=0;i<m->get_surface_count();i++) {
Ref<SpatialMaterial> fm = m->surface_get_material(i);
@@ -477,7 +477,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
MeshInstance *mi = p_node->cast_to<MeshInstance>();
- Ref<Mesh> mesh = mi->get_mesh();
+ Ref<ArrayMesh> mesh = mi->get_mesh();
ERR_FAIL_COND_V(mesh.is_null(), NULL);
NavigationMeshInstance *nmi = memnew(NavigationMeshInstance);
@@ -655,7 +655,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
MeshInstance *mi = p_node->cast_to<MeshInstance>();
- Ref<Mesh> mesh = mi->get_mesh();
+ Ref<ArrayMesh> mesh = mi->get_mesh();
if (!mesh.is_null()) {
if (_teststr(mesh->get_name(), "col")) {
@@ -972,7 +972,7 @@ static String _make_extname(const String &p_str) {
return ext_name;
}
-void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<Mesh>, Ref<Mesh> > &p_meshes) {
+void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) {
List<PropertyInfo> pi;
@@ -1005,7 +1005,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
}
} else {
- Ref<Mesh> mesh = p_node->get(E->get().name);
+ Ref<ArrayMesh> mesh = p_node->get(E->get().name);
if (mesh.is_valid()) {
@@ -1018,7 +1018,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
String ext_name = p_base_path + "." + _make_extname(mesh->get_name()) + ".msh";
if (FileAccess::exists(ext_name)) {
//if exists, use it
- Ref<Mesh> existing = ResourceLoader::load(ext_name);
+ Ref<ArrayMesh> existing = ResourceLoader::load(ext_name);
p_meshes[mesh] = existing;
} else {
@@ -1059,7 +1059,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
}
if (!p_make_meshes) {
- p_meshes[mesh] = Ref<Mesh>(); //save it anyway, so it won't be checked again
+ p_meshes[mesh] = Ref<ArrayMesh>(); //save it anyway, so it won't be checked again
}
}
}
@@ -1192,7 +1192,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
float anim_optimizer_angerr = p_options["animation/optimizer/max_angular_error"];
float anim_optimizer_maxang = p_options["animation/optimizer/max_angle"];
- Map<Ref<Mesh>, Ref<Shape> > collision_map;
+ Map<Ref<ArrayMesh>, Ref<Shape> > collision_map;
scene = _fix_node(scene, scene, collision_map);
@@ -1230,7 +1230,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
if (external_materials || external_meshes) {
Map<Ref<Material>, Ref<Material> > mat_map;
- Map<Ref<Mesh>, Ref<Mesh> > mesh_map;
+ Map<Ref<ArrayMesh>, Ref<ArrayMesh> > mesh_map;
_make_external_resources(scene, p_source_file.get_basename(), external_materials, external_meshes, mat_map, mesh_map);
}
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 9f7b1a84e6..ede3028b29 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -32,6 +32,7 @@
#include "io/resource_import.h"
#include "scene/resources/animation.h"
+#include "scene/resources/mesh.h"
#include "scene/resources/shape.h"
class Material;
@@ -100,9 +101,9 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<Mesh>, Ref<Mesh> > &p_meshes);
+ void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
- Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, Ref<Shape> > &collision_map);
+ Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map);
void _create_clips(Node *scene, const Array &p_clips, bool p_bake_all);
void _filter_anim_tracks(Ref<Animation> anim, Set<String> &keep);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 3536ecd094..61f6880433 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -3055,8 +3055,8 @@ void SpatialEditor::_init_indicators() {
for (int i = 0; i < 3; i++) {
- move_gizmo[i] = Ref<Mesh>(memnew(Mesh));
- rotate_gizmo[i] = Ref<Mesh>(memnew(Mesh));
+ move_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
+ rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 88245ad0dc..394002db3b 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -330,13 +330,13 @@ private:
bool grid_enable[3]; //should be always visible if true
bool grid_enabled;
- Ref<Mesh> move_gizmo[3], rotate_gizmo[3];
+ Ref<ArrayMesh> move_gizmo[3], rotate_gizmo[3];
Ref<SpatialMaterial> gizmo_color[3];
Ref<SpatialMaterial> gizmo_hl;
int over_gizmo_handle;
- Ref<Mesh> selection_box;
+ Ref<ArrayMesh> selection_box;
RID indicators;
RID indicators_instance;
RID cursor_mesh;
@@ -472,8 +472,8 @@ public:
float get_rotate_snap() const { return snap_rotate->get_text().to_double(); }
float get_scale_snap() const { return snap_scale->get_text().to_double(); }
- Ref<Mesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
- Ref<Mesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; }
+ Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
+ Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; }
void update_transform_gizmo();
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index 4781bb6a3b..149b06e50a 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -79,7 +79,7 @@ void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) {
VS::get_singleton()->instance_set_layer_mask(instance, 1 << SpatialEditorViewport::GIZMO_EDIT_LAYER); //gizmos are 26
}
-void EditorSpatialGizmo::add_mesh(const Ref<Mesh> &p_mesh, bool p_billboard, const RID &p_skeleton) {
+void EditorSpatialGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard, const RID &p_skeleton) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -100,7 +100,7 @@ void EditorSpatialGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Mat
ERR_FAIL_COND(!spatial_node);
Instance ins;
- Ref<Mesh> mesh = memnew(Mesh);
+ Ref<ArrayMesh> mesh = memnew(ArrayMesh);
Array a;
a.resize(Mesh::ARRAY_MAX);
@@ -162,7 +162,7 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material,
uv.push_back(Vector2(0, 1));
uv.push_back(Vector2(1, 1));
- Ref<Mesh> mesh = memnew(Mesh);
+ Ref<ArrayMesh> mesh = memnew(ArrayMesh);
Array a;
a.resize(Mesh::ARRAY_MAX);
a[Mesh::ARRAY_VERTEX] = vs;
@@ -219,7 +219,7 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
ERR_FAIL_COND(!spatial_node);
Instance ins;
- Ref<Mesh> mesh = memnew(Mesh);
+ Ref<ArrayMesh> mesh = memnew(ArrayMesh);
#if 1
Array a;
@@ -1029,7 +1029,7 @@ CameraSpatialGizmo::CameraSpatialGizmo(Camera *p_camera) {
void MeshInstanceSpatialGizmo::redraw() {
- Ref<Mesh> m = mesh->get_mesh();
+ Ref<ArrayMesh> m = mesh->get_mesh();
if (!m.is_valid())
return; //none
@@ -1248,7 +1248,7 @@ void SkeletonSpatialGizmo::redraw() {
*/
}
- Ref<Mesh> m = surface_tool->commit();
+ Ref<ArrayMesh> m = surface_tool->commit();
add_mesh(m, false, skel->get_skeleton());
}
@@ -2511,7 +2511,7 @@ void NavigationMeshSpatialGizmo::redraw() {
if (lines.size())
add_lines(lines, navmesh->is_enabled() ? SpatialEditorGizmos::singleton->navmesh_edge_material : SpatialEditorGizmos::singleton->navmesh_edge_material_disabled);
add_collision_triangles(tmesh);
- Ref<Mesh> m = memnew(Mesh);
+ Ref<ArrayMesh> m = memnew(ArrayMesh);
Array a;
a.resize(Mesh::ARRAY_MAX);
a[0] = tmeshfaces;
@@ -3213,7 +3213,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
//position 3D Shared mesh
- pos3d_mesh = Ref<Mesh>(memnew(Mesh));
+ pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
{
PoolVector<Vector3> cursor_points;
@@ -3246,7 +3246,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
pos3d_mesh->surface_set_material(0, mat);
}
- listener_line_mesh = Ref<Mesh>(memnew(Mesh));
+ listener_line_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
{
PoolVector<Vector3> cursor_points;
diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h
index 095586ab91..6a77e91425 100644
--- a/editor/spatial_editor_gizmos.h
+++ b/editor/spatial_editor_gizmos.h
@@ -59,7 +59,7 @@ class EditorSpatialGizmo : public SpatialEditorGizmo {
struct Instance {
RID instance;
- Ref<Mesh> mesh;
+ Ref<ArrayMesh> mesh;
RID skeleton;
bool billboard;
bool unscaled;
@@ -97,7 +97,7 @@ class EditorSpatialGizmo : public SpatialEditorGizmo {
protected:
void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false);
- void add_mesh(const Ref<Mesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID());
+ void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID());
void add_collision_segments(const Vector<Vector3> &p_lines);
void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1);
@@ -454,8 +454,8 @@ public:
Ref<SpatialMaterial> shape_material;
Ref<Texture> handle_t;
- Ref<Mesh> pos3d_mesh;
- Ref<Mesh> listener_line_mesh;
+ Ref<ArrayMesh> pos3d_mesh;
+ Ref<ArrayMesh> listener_line_mesh;
static SpatialEditorGizmos *singleton;
Ref<TriangleMesh> test_cube_tm;
diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h
index 9bc1fadd13..127833ebd0 100644
--- a/modules/hdr/image_loader_hdr.h
+++ b/modules/hdr/image_loader_hdr.h
@@ -27,8 +27,8 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef IMAGE_LOADER_TINYEXR_H
-#define IMAGE_LOADER_TINYEXR_H
+#ifndef IMAGE_LOADER_HDR_H
+#define IMAGE_LOADER_HDR_H
#include "io/image_loader.h"
diff --git a/modules/tga/SCsub b/modules/tga/SCsub
new file mode 100644
index 0000000000..7e405f405c
--- /dev/null
+++ b/modules/tga/SCsub
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+Import('env')
+Import('env_modules')
+
+env_tga = env_modules.Clone()
+
+# Godot's own source files
+env_tga.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/tga/config.py b/modules/tga/config.py
new file mode 100644
index 0000000000..fb920482f5
--- /dev/null
+++ b/modules/tga/config.py
@@ -0,0 +1,7 @@
+
+def can_build(platform):
+ return True
+
+
+def configure(env):
+ pass
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
new file mode 100644
index 0000000000..5b8610b975
--- /dev/null
+++ b/modules/tga/image_loader_tga.cpp
@@ -0,0 +1,314 @@
+/*************************************************************************/
+/* image_loader_jpegd.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "image_loader_tga.h"
+
+#include "os/os.h"
+#include "print_string.h"
+
+Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t p_pixel_size, uint8_t *p_uncompressed_buffer, size_t p_output_size) {
+ Error error;
+
+ PoolVector<uint8_t> pixels;
+ error = pixels.resize(p_pixel_size);
+ if (error != OK)
+ return error;
+
+ PoolVector<uint8_t>::Write pixels_w = pixels.write();
+
+ size_t compressed_pos = 0;
+ size_t output_pos = 0;
+ size_t c = 0;
+ size_t count = 0;
+
+ while (output_pos < p_output_size) {
+ c = p_compressed_buffer[compressed_pos];
+ compressed_pos += 1;
+ count = (c & 0x7f) + 1;
+
+ if (c & 0x80) {
+ for (int i = 0; i < p_pixel_size; i++) {
+ pixels_w.ptr()[i] = p_compressed_buffer[compressed_pos];
+ compressed_pos += 1;
+ }
+ for (int i = 0; i < count; i++) {
+ for (int j = 0; j < p_pixel_size; j++) {
+ p_uncompressed_buffer[output_pos + j] = pixels_w.ptr()[j];
+ }
+ output_pos += p_pixel_size;
+ }
+ } else {
+ count *= p_pixel_size;
+ for (int i = 0; i < count; i++) {
+ p_uncompressed_buffer[output_pos] = p_compressed_buffer[compressed_pos];
+ compressed_pos += 1;
+ output_pos += 1;
+ }
+ }
+ }
+ return OK;
+}
+
+Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome) {
+
+#define TGA_PUT_PIXEL(r, g, b, a) \
+ int image_data_ofs = ((y * width) + x); \
+ image_data_w[image_data_ofs * 4 + 0] = r; \
+ image_data_w[image_data_ofs * 4 + 1] = g; \
+ image_data_w[image_data_ofs * 4 + 2] = b; \
+ image_data_w[image_data_ofs * 4 + 3] = a;
+
+ uint32_t width = p_header.image_width;
+ uint32_t height = p_header.image_height;
+ tga_origin_e origin = static_cast<tga_origin_e>((p_header.image_descriptor & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT);
+
+ uint32_t x_start;
+ int32_t x_step;
+ uint32_t x_end;
+ uint32_t y_start;
+ int32_t y_step;
+ uint32_t y_end;
+
+ if (origin == TGA_ORIGIN_TOP_LEFT || origin == TGA_ORIGIN_TOP_RIGHT) {
+ y_start = 0;
+ y_step = 1;
+ y_end = height;
+ } else {
+ y_start = height - 1;
+ y_step = -1;
+ y_end = -1;
+ }
+
+ if (origin == TGA_ORIGIN_TOP_LEFT || origin == TGA_ORIGIN_BOTTOM_LEFT) {
+ x_start = 0;
+ x_step = 1;
+ x_end = width;
+ } else {
+ x_start = width - 1;
+ x_step = -1;
+ x_end = -1;
+ }
+
+ PoolVector<uint8_t> image_data;
+ image_data.resize(width * height * sizeof(uint32_t));
+ PoolVector<uint8_t>::Write image_data_w = image_data.write();
+
+ size_t i = 0;
+ uint32_t x = x_start;
+ uint32_t y = y_start;
+
+ if (p_header.pixel_depth == 8) {
+ if (p_is_monochrome) {
+ while (y != y_end) {
+ while (x != x_end) {
+ uint8_t shade = p_buffer[i];
+
+ TGA_PUT_PIXEL(shade, shade, shade, 0xff)
+
+ x += x_step;
+ i += 1;
+ }
+ x = x_start;
+ y += y_step;
+ }
+ } else {
+ while (y != y_end) {
+ while (x != x_end) {
+ uint8_t index = p_buffer[i];
+ uint8_t r = 0x00;
+ uint8_t g = 0x00;
+ uint8_t b = 0x00;
+ uint8_t a = 0xff;
+
+ if (p_header.color_map_depth == 24) {
+ r = (p_palette[(index * 3) + 0]);
+ g = (p_palette[(index * 3) + 1]);
+ b = (p_palette[(index * 3) + 2]);
+ } else {
+ return ERR_INVALID_DATA;
+ }
+
+ TGA_PUT_PIXEL(r, g, b, a)
+
+ x += x_step;
+ i += 1;
+ }
+ x = x_start;
+ y += y_step;
+ }
+ }
+ } else if (p_header.pixel_depth == 24) {
+ while (y != y_end) {
+ while (x != x_end) {
+ uint8_t r = p_buffer[i + 2];
+ uint8_t g = p_buffer[i + 1];
+ uint8_t b = p_buffer[i + 0];
+
+ TGA_PUT_PIXEL(r, g, b, 0xff)
+
+ x += x_step;
+ i += 3;
+ }
+ x = x_start;
+ y += y_step;
+ }
+ } else if (p_header.pixel_depth == 32) {
+ while (y != y_end) {
+ while (x != x_end) {
+ uint8_t a = p_buffer[i + 3];
+ uint8_t r = p_buffer[i + 2];
+ uint8_t g = p_buffer[i + 1];
+ uint8_t b = p_buffer[i + 0];
+
+ TGA_PUT_PIXEL(r, g, b, a)
+
+ x += x_step;
+ i += 4;
+ }
+ x = x_start;
+ y += y_step;
+ }
+ }
+
+ image_data_w = PoolVector<uint8_t>::Write();
+
+ p_image->create(width, height, 0, Image::FORMAT_RGBA8, image_data);
+
+ return OK;
+}
+
+Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
+
+ PoolVector<uint8_t> src_image;
+ int src_image_len = f->get_len();
+ ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V(src_image_len < sizeof(tga_header_s), ERR_FILE_CORRUPT);
+ src_image.resize(src_image_len);
+
+ Error err = OK;
+
+ tga_header_s tga_header;
+ tga_header.id_length = f->get_8();
+ tga_header.color_map_type = f->get_8();
+ tga_header.image_type = static_cast<tga_type_e>(f->get_8());
+
+ tga_header.first_color_entry = f->get_16();
+ tga_header.color_map_length = f->get_16();
+ tga_header.color_map_depth = f->get_8();
+
+ tga_header.x_origin = f->get_16();
+ tga_header.y_origin = f->get_16();
+ tga_header.image_width = f->get_16();
+ tga_header.image_height = f->get_16();
+ tga_header.pixel_depth = f->get_8();
+ tga_header.image_descriptor = f->get_8();
+
+ bool is_encoded = (tga_header.image_type == TGA_TYPE_RLE_INDEXED || tga_header.image_type == TGA_TYPE_RLE_RGB || tga_header.image_type == TGA_TYPE_RLE_MONOCHROME);
+ bool has_color_map = (tga_header.image_type == TGA_TYPE_RLE_INDEXED || tga_header.image_type == TGA_TYPE_INDEXED);
+ bool is_monochrome = (tga_header.image_type == TGA_TYPE_RLE_MONOCHROME || tga_header.image_type == TGA_TYPE_MONOCHROME);
+
+ if (tga_header.image_type == TGA_TYPE_NO_DATA)
+ err = FAILED;
+
+ if (has_color_map) {
+ if (tga_header.color_map_length > 256 || (tga_header.color_map_depth != 24) || tga_header.color_map_type != 1) {
+ err = FAILED;
+ }
+ } else {
+ if (tga_header.color_map_type) {
+ err = FAILED;
+ }
+ }
+
+ if (tga_header.image_width <= 0 || tga_header.image_height <= 0)
+ err = FAILED;
+
+ if (tga_header.pixel_depth != 8 && tga_header.pixel_depth != 24 && tga_header.pixel_depth != 32)
+ err = FAILED;
+
+ if (err == OK) {
+ f->seek(f->get_pos() + tga_header.id_length);
+
+ PoolVector<uint8_t> palette;
+
+ if (has_color_map) {
+ size_t color_map_size = tga_header.color_map_length * (tga_header.color_map_depth >> 3);
+ err = palette.resize(color_map_size);
+ if (err == OK) {
+ PoolVector<uint8_t>::Write palette_w = palette.write();
+ f->get_buffer(&palette_w[0], color_map_size);
+ } else {
+ return OK;
+ }
+ }
+
+ PoolVector<uint8_t>::Write src_image_w = src_image.write();
+ f->get_buffer(&src_image_w[0], src_image_len - f->get_pos());
+
+ PoolVector<uint8_t>::Read src_image_r = src_image.read();
+
+ const size_t pixel_size = tga_header.pixel_depth >> 3;
+ const size_t buffer_size = (tga_header.image_width * tga_header.image_height) * pixel_size;
+
+ PoolVector<uint8_t> uncompressed_buffer;
+ uncompressed_buffer.resize(buffer_size);
+ PoolVector<uint8_t>::Write uncompressed_buffer_w = uncompressed_buffer.write();
+ PoolVector<uint8_t>::Read uncompressed_buffer_r;
+
+ const uint8_t *buffer = NULL;
+
+ if (is_encoded) {
+
+ err = decode_tga_rle(src_image_r.ptr(), pixel_size, uncompressed_buffer_w.ptr(), buffer_size);
+
+ if (err == OK) {
+ uncompressed_buffer_r = uncompressed_buffer.read();
+ buffer = uncompressed_buffer_r.ptr();
+ }
+ } else {
+ buffer = src_image_r.ptr();
+ };
+
+ if (err == OK) {
+ PoolVector<uint8_t>::Read palette_r = palette.read();
+ err = convert_to_image(p_image, buffer, tga_header, palette_r.ptr(), is_monochrome);
+ }
+ }
+
+ f->close();
+ return err;
+}
+
+void ImageLoaderTGA::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("tga");
+}
+
+ImageLoaderTGA::ImageLoaderTGA() {
+}
diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h
new file mode 100644
index 0000000000..11329ec68a
--- /dev/null
+++ b/modules/tga/image_loader_tga.h
@@ -0,0 +1,83 @@
+/*************************************************************************/
+/* image_loader_jpegd.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef IMAGE_LOADER_TGA_H
+#define IMAGE_LOADER_TGA_H
+
+#include "io/image_loader.h"
+
+/**
+ @author SaracenOne
+*/
+class ImageLoaderTGA : public ImageFormatLoader {
+ enum tga_type_e {
+ TGA_TYPE_NO_DATA = 0,
+ TGA_TYPE_INDEXED = 1,
+ TGA_TYPE_RGB = 2,
+ TGA_TYPE_MONOCHROME = 3,
+ TGA_TYPE_RLE_INDEXED = 9,
+ TGA_TYPE_RLE_RGB = 10,
+ TGA_TYPE_RLE_MONOCHROME = 11
+ };
+
+ enum tga_origin_e {
+ TGA_ORIGIN_BOTTOM_LEFT = 0x00,
+ TGA_ORIGIN_BOTTOM_RIGHT = 0x01,
+ TGA_ORIGIN_TOP_LEFT = 0x02,
+ TGA_ORIGIN_TOP_RIGHT = 0x03,
+ TGA_ORIGIN_SHIFT = 0x04,
+ TGA_ORIGIN_MASK = 0x30
+ };
+
+ struct tga_header_s {
+ uint8_t id_length;
+ uint8_t color_map_type;
+ tga_type_e image_type;
+
+ uint16_t first_color_entry;
+ uint16_t color_map_length;
+ uint8_t color_map_depth;
+
+ uint16_t x_origin;
+ uint16_t y_origin;
+ uint16_t image_width;
+ uint16_t image_height;
+ uint8_t pixel_depth;
+ uint8_t image_descriptor;
+ };
+ static Error decode_tga_rle(const uint8_t *p_compressed_buffer, size_t p_pixel_size, uint8_t *p_uncompressed_buffer, size_t p_output_size);
+ static Error convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome);
+
+public:
+ virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ ImageLoaderTGA();
+};
+
+#endif
diff --git a/modules/tga/register_types.cpp b/modules/tga/register_types.cpp
new file mode 100644
index 0000000000..6e120fa3bf
--- /dev/null
+++ b/modules/tga/register_types.cpp
@@ -0,0 +1,45 @@
+/*************************************************************************/
+/* register_types.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "register_types.h"
+
+#include "image_loader_tga.h"
+
+static ImageLoaderTGA *image_loader_tga = NULL;
+
+void register_tga_types() {
+
+ image_loader_tga = memnew(ImageLoaderTGA);
+ ImageLoader::add_image_format_loader(image_loader_tga);
+}
+
+void unregister_tga_types() {
+
+ memdelete(image_loader_tga);
+}
diff --git a/modules/tga/register_types.h b/modules/tga/register_types.h
new file mode 100644
index 0000000000..079b7bf291
--- /dev/null
+++ b/modules/tga/register_types.h
@@ -0,0 +1,31 @@
+/*************************************************************************/
+/* register_types.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+void register_tga_types();
+void unregister_tga_types();
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 37f53a2478..d4bd443689 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -1367,7 +1367,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env
jevent.device = p_device;
jevent.type = OS_Android::JOY_EVENT_BUTTON;
jevent.index = p_button;
- jevent->is_pressed() = p_pressed;
+ jevent.pressed = p_pressed;
input_mutex->lock();
joy_events.push_back(jevent);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 6e8b46e252..9010b9e7da 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -344,7 +344,7 @@ void OS_Android::process_joy_event(OS_Android::JoypadEvent p_event) {
switch (p_event.type) {
case JOY_EVENT_BUTTON:
- input->joy_button(p_event.device, p_event.index, p_event->is_pressed());
+ input->joy_button(p_event.device, p_event.index, p_event.pressed);
break;
case JOY_EVENT_AXIS:
InputDefault::JoyAxis value;
@@ -406,7 +406,7 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
//send mouse
Ref<InputEventMouseButton> ev;
ev.instance();
- ev.type = Ref<InputEvent>::MOUSE_BUTTON;
+ // ev.type = Ref<InputEvent>::MOUSE_BUTTON;
ev->set_button_index(BUTTON_LEFT);
ev->set_button_mask(BUTTON_MASK_LEFT);
ev->set_pressed(true);
@@ -424,7 +424,7 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
ev.instance();
ev->set_index(touch[i].id);
ev->set_pressed(true);
- ev->set_position(touch[i].pos.x);
+ ev->set_position(touch[i].pos);
input->parse_input_event(ev);
}
@@ -436,8 +436,8 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
Ref<InputEventMouseMotion> ev;
ev.instance();
ev->set_button_mask(BUTTON_MASK_LEFT);
- ev->set_position(p_points[0].pos.x);
- input->set_mouse_position(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
+ ev->set_position(p_points[0].pos);
+ input->set_mouse_position(Point2(ev->get_position().x, ev->get_position().y));
ev->set_speed(input->get_last_mouse_speed());
ev->set_relative(p_points[0].pos - last_mouse);
last_mouse = p_points[0].pos;
@@ -465,7 +465,7 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
Ref<InputEventScreenDrag> ev;
ev.instance();
ev->set_index(touch[i].id);
- ev->set_position(p_points[idx].pos.x);
+ ev->set_position(p_points[idx].pos);
ev->set_relative(p_points[idx].pos - touch[i].pos);
input->parse_input_event(ev);
touch[i].pos = p_points[idx].pos;
@@ -481,8 +481,8 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
ev->set_button_index(BUTTON_LEFT);
ev->set_button_mask(BUTTON_MASK_LEFT);
ev->set_pressed(false);
- ev->set_position(touch[0].pos.x);
- ev->set_global_position(touch[0].pos.x);
+ ev->set_position(touch[0].pos);
+ ev->set_global_position(touch[0].pos);
input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y));
input->parse_input_event(ev);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index cb37f18090..54b1802250 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -365,7 +365,7 @@ static int button_mask = 0;
- (void)rightMouseUp:(NSEvent *)event {
- button_mask |= BUTTON_MASK_RIGHT;
+ button_mask &= ~BUTTON_MASK_RIGHT;
Ref<InputEventMouseButton> mb;
mb.instance();
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/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/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/mesh.cpp b/scene/resources/mesh.cpp
index 4846d84b33..e2ede41290 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,7 +688,7 @@ 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;
@@ -313,7 +697,7 @@ void Mesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolV
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 +729,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 +773,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 +791,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 +849,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 +894,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 +902,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 +950,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 +967,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 +1036,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 +1114,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/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 723c5737cd..9dfb0b2e71 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -71,6 +71,10 @@ public:
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0;
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
+
struct InstanceBase : RID_Data {
VS::InstanceType base_type;
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 44ec13af45..e0201420fe 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -105,6 +105,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECIAL"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DISCARD"] = ShaderLanguage::TYPE_BOOL;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DEPTH_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SIDE"] = ShaderLanguage::TYPE_FLOAT;
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 957af7b9dd..8c311300ad 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -950,6 +950,10 @@ public:
BIND6(environment_set_adjustment, RID, bool, float, float, float, RID)
+ BIND5(environment_set_fog, RID, bool, const Color &, const Color &, float)
+ BIND6(environment_set_fog_depth, RID, bool, float, float, bool, float)
+ BIND5(environment_set_fog_height, RID, bool, float, float, float)
+
/* SCENARIO API */
#undef BINDBASE
diff --git a/servers/visual_server.h b/servers/visual_server.h
index aa98d47455..3d5ca9d99a 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -638,6 +638,10 @@ public:
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_accel, float p_fade, float p_depth_tolerance, bool p_smooth, bool p_roughness) = 0;
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) = 0;
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
+
/* SCENARIO API */
virtual RID scenario_create() = 0;