summaryrefslogtreecommitdiff
path: root/editor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/baked_light_baker.cpp10
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.cpp20
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.h4
-rw-r--r--editor/plugins/curve_editor_plugin.cpp519
-rw-r--r--editor/plugins/curve_editor_plugin.h66
-rw-r--r--editor/plugins/gradient_texture_editor_plugin.cpp504
-rw-r--r--editor/plugins/gradient_texture_editor_plugin.h69
-rw-r--r--editor/plugins/particles_editor_plugin.cpp352
-rw-r--r--editor/plugins/particles_editor_plugin.h22
-rw-r--r--editor/plugins/path_editor_plugin.cpp12
-rw-r--r--editor/plugins/path_editor_plugin.h4
-rw-r--r--editor/plugins/shader_editor_plugin.cpp29
-rw-r--r--editor/plugins/shader_editor_plugin.h2
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp38
-rw-r--r--editor/plugins/spatial_editor_plugin.h8
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp2
16 files changed, 1435 insertions, 226 deletions
diff --git a/editor/plugins/baked_light_baker.cpp b/editor/plugins/baked_light_baker.cpp
index de2b78b8dd..3db54978e1 100644
--- a/editor/plugins/baked_light_baker.cpp
+++ b/editor/plugins/baked_light_baker.cpp
@@ -144,18 +144,18 @@ void BakedLightBaker::_add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_m
MeshMaterial mm;
- Ref<FixedSpatialMaterial> fm = mat;
+ Ref<SpatialMaterial> fm = mat;
if (fm.is_valid()) {
//fixed route
- mm.diffuse.color=fm->get_parameter(FixedSpatialMaterial::PARAM_DIFFUSE);
+ mm.diffuse.color=fm->get_parameter(SpatialMaterial::PARAM_DIFFUSE);
if (linear_color)
mm.diffuse.color=mm.diffuse.color.to_linear();
- mm.diffuse.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_DIFFUSE));
- mm.specular.color=fm->get_parameter(FixedSpatialMaterial::PARAM_SPECULAR);
+ mm.diffuse.tex=_get_mat_tex(fm->get_texture(SpatialMaterial::PARAM_DIFFUSE));
+ mm.specular.color=fm->get_parameter(SpatialMaterial::PARAM_SPECULAR);
if (linear_color)
mm.specular.color=mm.specular.color.to_linear();
- mm.specular.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_SPECULAR));
+ mm.specular.tex=_get_mat_tex(fm->get_texture(SpatialMaterial::PARAM_SPECULAR));
} else {
mm.diffuse.color=Color(1,1,1,1);
diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp
index 62426a7699..c0599bf26e 100644
--- a/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -571,25 +571,25 @@ CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) {
imgeom->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001)));
- line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
+ line_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
line_material->set_flag(Material::FLAG_UNSHADED, true);
line_material->set_line_width(3.0);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
- line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
- line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
+ line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
+ line_material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
- handle_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
+ handle_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
handle_material->set_flag(Material::FLAG_UNSHADED, true);
- handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_POINT_SIZE, true);
- handle_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
- handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
- handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, false);
+ handle_material->set_fixed_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true);
+ handle_material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
+ handle_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
+ handle_material->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY, false);
Ref<Texture> handle=editor->get_gui_base()->get_icon("Editor3DHandle","EditorIcons");
handle_material->set_point_size(handle->get_width());
- handle_material->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,handle);
+ handle_material->set_texture(SpatialMaterial::PARAM_DIFFUSE,handle);
pointsm = memnew( MeshInstance );
imgeom->add_child(pointsm);
diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h
index ace8c3429f..d033fbf2ed 100644
--- a/editor/plugins/collision_polygon_editor_plugin.h
+++ b/editor/plugins/collision_polygon_editor_plugin.h
@@ -62,8 +62,8 @@ class CollisionPolygonEditor : public HBoxContainer {
ToolButton *button_edit;
- Ref<FixedSpatialMaterial> line_material;
- Ref<FixedSpatialMaterial> handle_material;
+ Ref<SpatialMaterial> line_material;
+ Ref<SpatialMaterial> handle_material;
EditorNode *editor;
Panel *panel;
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
new file mode 100644
index 0000000000..52edc75bc0
--- /dev/null
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -0,0 +1,519 @@
+#include "curve_editor_plugin.h"
+
+#include "canvas_item_editor_plugin.h"
+#include "os/keyboard.h"
+#include "spatial_editor_plugin.h"
+void CurveTextureEdit::_gui_input(const InputEvent &p_event) {
+
+ if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode == KEY_DELETE && grabbed != -1) {
+
+ points.remove(grabbed);
+ grabbed = -1;
+ update();
+ emit_signal("curve_changed");
+ accept_event();
+ }
+
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed) {
+
+ update();
+ Ref<Font> font = get_font("font", "Label");
+
+ int font_h = font->get_height();
+
+ Vector2 size = get_size();
+ size.y -= font_h;
+
+ Point2 p = Vector2(p_event.mouse_button.x, p_event.mouse_button.y) / size;
+ p.y = CLAMP(1.0 - p.y, 0, 1) * (max - min) + min;
+ grabbed = -1;
+ grabbing = true;
+
+ for (int i = 0; i < points.size(); i++) {
+
+ Vector2 ps = p * get_size();
+ Vector2 pt = Vector2(points[i].offset, points[i].height) * get_size();
+ if (ps.distance_to(pt) < 4) {
+ grabbed = i;
+ }
+ }
+
+ //grab or select
+ if (grabbed != -1) {
+ return;
+ }
+ //insert
+
+ Point np;
+ np.offset = p.x;
+ np.height = p.y;
+
+ points.push_back(np);
+ points.sort();
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset == p.x && points[i].height == p.y) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("curve_changed");
+ }
+
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && !p_event.mouse_button.pressed) {
+
+ if (grabbing) {
+ grabbing = false;
+ emit_signal("curve_changed");
+ }
+ update();
+ }
+
+ if (p_event.type == InputEvent::MOUSE_MOTION && grabbing && grabbed != -1) {
+
+ Ref<Font> font = get_font("font", "Label");
+ int font_h = font->get_height();
+ Vector2 size = get_size();
+ size.y -= font_h;
+
+ Point2 p = Vector2(p_event.mouse_motion.x, p_event.mouse_motion.y) / size;
+ p.y = CLAMP(1.0 - p.y, 0, 1) * (max - min) + min;
+ p.x = CLAMP(p.x, 0.0, 1.0);
+
+ bool valid = true;
+
+ for (int i = 0; i < points.size(); i++) {
+
+ if (points[i].offset == p.x && points[i].height == p.y && i != grabbed) {
+ valid = false;
+ }
+ }
+
+ if (!valid)
+ return;
+
+ points[grabbed].offset = p.x;
+ points[grabbed].height = p.y;
+
+ points.sort();
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset == p.x && points[i].height == p.y) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("curve_changed");
+
+ update();
+ }
+}
+
+void CurveTextureEdit::_plot_curve(const Vector2 &p_a, const Vector2 &p_b, const Vector2 &p_c, const Vector2 &p_d) {
+
+ Ref<Font> font = get_font("font", "Label");
+
+ int font_h = font->get_height();
+
+ float geometry[4][4];
+ float tmp1[4][4];
+ float tmp2[4][4];
+ float deltas[4][4];
+ double x, dx, dx2, dx3;
+ double y, dy, dy2, dy3;
+ double d, d2, d3;
+ int lastx, lasty;
+ int newx, newy;
+ int ntimes;
+ int i, j;
+
+ int xmax = get_size().x;
+ int ymax = get_size().y - font_h;
+
+ int vsplits = 4;
+
+ int zero_ofs = (1.0 - (0.0 - min) / (max - min)) * ymax;
+
+ draw_line(Vector2(0, zero_ofs), Vector2(xmax, zero_ofs), Color(0.8, 0.8, 0.8, 0.15), 2.0);
+
+ for (int i = 0; i <= vsplits; i++) {
+ float fofs = float(i) / vsplits;
+ int yofs = fofs * ymax;
+ draw_line(Vector2(xmax, yofs), Vector2(xmax - 4, yofs), Color(0.8, 0.8, 0.8, 0.8), 2.0);
+
+ String text = rtos((1.0 - fofs) * (max - min) + min);
+ int ppos = text.find(".");
+ if (ppos != -1) {
+ if (text.length() > ppos + 2)
+ text = text.substr(0, ppos + 2);
+ }
+
+ int size = font->get_string_size(text).x;
+ int xofs = xmax - size - 4;
+ yofs -= font_h / 2;
+
+ if (yofs < 2) {
+ yofs = 2;
+ } else if (yofs + font_h > ymax - 2) {
+ yofs = ymax - font_h - 2;
+ }
+
+ draw_string(font, Vector2(xofs, yofs + font->get_ascent()), text, Color(0.8, 0.8, 0.8, 1));
+ }
+
+ /* construct the geometry matrix from the segment */
+ for (i = 0; i < 4; i++) {
+ geometry[i][2] = 0;
+ geometry[i][3] = 0;
+ }
+
+ geometry[0][0] = (p_a[0] * xmax);
+ geometry[1][0] = (p_b[0] * xmax);
+ geometry[2][0] = (p_c[0] * xmax);
+ geometry[3][0] = (p_d[0] * xmax);
+
+ geometry[0][1] = ((p_a[1] - min) / (max - min) * ymax);
+ geometry[1][1] = ((p_b[1] - min) / (max - min) * ymax);
+ geometry[2][1] = ((p_c[1] - min) / (max - min) * ymax);
+ geometry[3][1] = ((p_d[1] - min) / (max - min) * ymax);
+
+ /* subdivide the curve ntimes (1000) times */
+ ntimes = 4 * xmax;
+ /* ntimes can be adjusted to give a finer or coarser curve */
+ d = 1.0 / ntimes;
+ d2 = d * d;
+ d3 = d * d * d;
+
+ /* construct a temporary matrix for determining the forward differencing deltas */
+ tmp2[0][0] = 0;
+ tmp2[0][1] = 0;
+ tmp2[0][2] = 0;
+ tmp2[0][3] = 1;
+ tmp2[1][0] = d3;
+ tmp2[1][1] = d2;
+ tmp2[1][2] = d;
+ tmp2[1][3] = 0;
+ tmp2[2][0] = 6 * d3;
+ tmp2[2][1] = 2 * d2;
+ tmp2[2][2] = 0;
+ tmp2[2][3] = 0;
+ tmp2[3][0] = 6 * d3;
+ tmp2[3][1] = 0;
+ tmp2[3][2] = 0;
+ tmp2[3][3] = 0;
+
+ /* compose the basis and geometry matrices */
+
+ static const float CR_basis[4][4] = {
+ { -0.5, 1.5, -1.5, 0.5 },
+ { 1.0, -2.5, 2.0, -0.5 },
+ { -0.5, 0.0, 0.5, 0.0 },
+ { 0.0, 1.0, 0.0, 0.0 },
+ };
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ tmp1[i][j] = (CR_basis[i][0] * geometry[0][j] +
+ CR_basis[i][1] * geometry[1][j] +
+ CR_basis[i][2] * geometry[2][j] +
+ CR_basis[i][3] * geometry[3][j]);
+ }
+ }
+ /* compose the above results to get the deltas matrix */
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ deltas[i][j] = (tmp2[i][0] * tmp1[0][j] +
+ tmp2[i][1] * tmp1[1][j] +
+ tmp2[i][2] * tmp1[2][j] +
+ tmp2[i][3] * tmp1[3][j]);
+ }
+ }
+
+ /* extract the x deltas */
+ x = deltas[0][0];
+ dx = deltas[1][0];
+ dx2 = deltas[2][0];
+ dx3 = deltas[3][0];
+
+ /* extract the y deltas */
+ y = deltas[0][1];
+ dy = deltas[1][1];
+ dy2 = deltas[2][1];
+ dy3 = deltas[3][1];
+
+ lastx = CLAMP(x, 0, xmax);
+ lasty = CLAMP(y, 0, ymax);
+
+ /* if (fix255)
+ {
+ cd->curve[cd->outline][lastx] = lasty;
+ }
+ else
+ {
+ cd->curve_ptr[cd->outline][lastx] = lasty;
+ if(gb_debug) printf("bender_plot_curve xmax:%d ymax:%d\n", (int)xmax, (int)ymax);
+ }
+*/
+ /* loop over the curve */
+ for (i = 0; i < ntimes; i++) {
+ /* increment the x values */
+ x += dx;
+ dx += dx2;
+ dx2 += dx3;
+
+ /* increment the y values */
+ y += dy;
+ dy += dy2;
+ dy2 += dy3;
+
+ newx = CLAMP((Math::round(x)), 0, xmax);
+ newy = CLAMP((Math::round(y)), 0, ymax);
+
+ /* if this point is different than the last one...then draw it */
+ if ((lastx != newx) || (lasty != newy)) {
+#if 0
+ if(fix255)
+ {
+ /* use fixed array size (for the curve graph) */
+ cd->curve[cd->outline][newx] = newy;
+ }
+ else
+ {
+ /* use dynamic allocated curve_ptr (for the real curve) */
+ cd->curve_ptr[cd->outline][newx] = newy;
+
+ if(gb_debug) printf("outline: %d cX: %d cY: %d\n", (int)cd->outline, (int)newx, (int)newy);
+ }
+#endif
+ draw_line(Vector2(lastx, ymax - lasty), Vector2(newx, ymax - newy), Color(0.8, 0.8, 0.8, 0.8), 2.0);
+ }
+
+ lastx = newx;
+ lasty = newy;
+ }
+
+ int splits = 8;
+
+ draw_line(Vector2(0, ymax - 1), Vector2(xmax, ymax - 1), Color(0.8, 0.8, 0.8, 0.3), 2.0);
+
+ for (int i = 0; i <= splits; i++) {
+ float fofs = float(i) / splits;
+ draw_line(Vector2(fofs * xmax, ymax), Vector2(fofs * xmax, ymax - 2), Color(0.8, 0.8, 0.8, 0.8), 2.0);
+
+ String text = rtos(fofs);
+ int size = font->get_string_size(text).x;
+ int ofs = fofs * xmax - size * 0.5;
+ if (ofs < 2) {
+ ofs = 2;
+ } else if (ofs + size > xmax - 2) {
+ ofs = xmax - size - 2;
+ }
+
+ draw_string(font, Vector2(ofs, ymax + font->get_ascent()), text, Color(0.8, 0.8, 0.8, 1));
+ }
+}
+
+void CurveTextureEdit::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_DRAW) {
+
+ Ref<Font> font = get_font("font", "Label");
+
+ int font_h = font->get_height();
+
+ draw_style_box(get_stylebox("bg", "Tree"), Rect2(Point2(), get_size()));
+
+ int w = get_size().x;
+ int h = get_size().y;
+
+ Vector2 prev = Vector2(0, 0);
+ Vector2 prev2 = Vector2(0, 0);
+
+ for (int i = -1; i < points.size(); i++) {
+
+ Vector2 next;
+ Vector2 next2;
+ if (i + 1 >= points.size()) {
+ next = Vector2(1, 0);
+ } else {
+ next = Vector2(points[i + 1].offset, points[i + 1].height);
+ }
+
+ if (i + 2 >= points.size()) {
+ next2 = Vector2(1, 0);
+ } else {
+ next2 = Vector2(points[i + 2].offset, points[i + 2].height);
+ }
+
+ /*if (i==-1 && prev.offset==next.offset) {
+ prev=next;
+ continue;
+ }*/
+
+ _plot_curve(prev2, prev, next, next2);
+
+ prev2 = prev;
+ prev = next;
+ }
+
+ Vector2 size = get_size();
+ size.y -= font_h;
+ for (int i = 0; i < points.size(); i++) {
+
+ Color col = i == grabbed ? Color(1, 0.0, 0.0, 0.9) : Color(1, 1, 1, 0.8);
+
+ float h = (points[i].height - min) / (max - min);
+ draw_rect(Rect2(Vector2(points[i].offset, 1.0 - h) * size - Vector2(2, 2), Vector2(5, 5)), col);
+ }
+
+ /* if (grabbed!=-1) {
+
+ draw_rect(Rect2(total_w+3,0,h,h),points[grabbed].color);
+ }
+*/
+ if (has_focus()) {
+
+ draw_line(Vector2(-1, -1), Vector2(w + 1, -1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(w + 1, -1), Vector2(w + 1, h + 1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(w + 1, h + 1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
+ }
+ }
+}
+
+Size2 CurveTextureEdit::get_minimum_size() const {
+
+ return Vector2(64, 64);
+}
+
+void CurveTextureEdit::set_range(float p_min, float p_max) {
+ max = p_max;
+ min = p_min;
+ update();
+}
+
+void CurveTextureEdit::set_points(const Vector<Vector2> &p_points) {
+
+ points.clear();
+ for (int i = 0; i < p_points.size(); i++) {
+ Point p;
+ p.offset = p_points[i].x;
+ p.height = p_points[i].y;
+ points.push_back(p);
+ }
+
+ points.sort();
+ update();
+}
+
+Vector<Vector2> CurveTextureEdit::get_points() const {
+ Vector<Vector2> ret;
+ for (int i = 0; i < points.size(); i++)
+ ret.push_back(Vector2(points[i].offset, points[i].height));
+ return ret;
+}
+
+void CurveTextureEdit::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_gui_input"), &CurveTextureEdit::_gui_input);
+
+ ADD_SIGNAL(MethodInfo("curve_changed"));
+}
+
+CurveTextureEdit::CurveTextureEdit() {
+
+ grabbed = -1;
+ grabbing = false;
+ max = 1;
+ min = 0;
+ set_focus_mode(FOCUS_ALL);
+}
+
+void CurveTextureEditorPlugin::_curve_settings_changed() {
+
+ if (!curve_texture_ref.is_valid())
+ return;
+ curve_editor->set_points(Variant(curve_texture_ref->get_points()));
+ curve_editor->set_range(curve_texture_ref->get_min(), curve_texture_ref->get_max());
+}
+
+CurveTextureEditorPlugin::CurveTextureEditorPlugin(EditorNode *p_node) {
+
+ editor = p_node;
+ curve_editor = memnew(CurveTextureEdit);
+
+ curve_button = editor->add_bottom_panel_item("CurveTexture", curve_editor);
+
+ curve_button->hide();
+ curve_editor->set_custom_minimum_size(Size2(100, 128 * EDSCALE));
+ curve_editor->hide();
+ curve_editor->connect("curve_changed", this, "curve_changed");
+}
+
+void CurveTextureEditorPlugin::edit(Object *p_object) {
+
+ if (curve_texture_ref.is_valid()) {
+ curve_texture_ref->disconnect("changed", this, "_curve_settings_changed");
+ }
+ CurveTexture *curve_texture = p_object->cast_to<CurveTexture>();
+ if (!curve_texture)
+ return;
+ curve_texture_ref = Ref<CurveTexture>(curve_texture);
+ curve_editor->set_points(Variant(curve_texture_ref->get_points()));
+ curve_editor->set_range(curve_texture_ref->get_min(), curve_texture_ref->get_max());
+ if (!curve_texture_ref->is_connected("changed", this, "_curve_settings_changed")) {
+ curve_texture_ref->connect("changed", this, "_curve_settings_changed");
+ }
+}
+
+bool CurveTextureEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_class("CurveTexture");
+}
+
+void CurveTextureEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+ curve_button->show();
+ editor->make_bottom_panel_item_visible(curve_editor);
+
+ } else {
+
+ curve_button->hide();
+ if (curve_editor->is_visible_in_tree())
+ editor->hide_bottom_panel();
+ }
+}
+
+void CurveTextureEditorPlugin::_curve_changed() {
+
+ if (curve_texture_ref.is_valid()) {
+
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ Vector<Vector2> points = curve_editor->get_points();
+ PoolVector<Vector2> ppoints = Variant(points);
+
+ ur->create_action(TTR("Modify Curve"), UndoRedo::MERGE_ENDS);
+ ur->add_do_method(this, "undo_redo_curve_texture", ppoints);
+ ur->add_undo_method(this, "undo_redo_curve_texture", curve_texture_ref->get_points());
+ ur->commit_action();
+ }
+}
+
+void CurveTextureEditorPlugin::_undo_redo_curve_texture(const PoolVector<Vector2> &points) {
+
+ curve_texture_ref->set_points(points);
+ curve_editor->set_points(Variant(curve_texture_ref->get_points()));
+ curve_editor->update();
+}
+
+CurveTextureEditorPlugin::~CurveTextureEditorPlugin() {
+}
+
+void CurveTextureEditorPlugin::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("curve_changed"), &CurveTextureEditorPlugin::_curve_changed);
+ ClassDB::bind_method(D_METHOD("_curve_settings_changed"), &CurveTextureEditorPlugin::_curve_settings_changed);
+ ClassDB::bind_method(D_METHOD("undo_redo_curve_texture", "points"), &CurveTextureEditorPlugin::_undo_redo_curve_texture);
+}
diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h
new file mode 100644
index 0000000000..e98cec2727
--- /dev/null
+++ b/editor/plugins/curve_editor_plugin.h
@@ -0,0 +1,66 @@
+#ifndef CURVE_EDITOR_PLUGIN_H
+#define CURVE_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+
+class CurveTextureEdit : public Control {
+
+ GDCLASS(CurveTextureEdit, Control);
+
+ struct Point {
+
+ float offset;
+ float height;
+ bool operator<(const Point &p_ponit) const {
+ return offset < p_ponit.offset;
+ }
+ };
+
+ bool grabbing;
+ int grabbed;
+ Vector<Point> points;
+ float max, min;
+
+ void _plot_curve(const Vector2 &p_a, const Vector2 &p_b, const Vector2 &p_c, const Vector2 &p_d);
+
+protected:
+ void _gui_input(const InputEvent &p_event);
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_range(float p_min, float p_max);
+ void set_points(const Vector<Vector2> &p_points);
+ Vector<Vector2> get_points() const;
+ virtual Size2 get_minimum_size() const;
+ CurveTextureEdit();
+};
+
+class CurveTextureEditorPlugin : public EditorPlugin {
+
+ GDCLASS(CurveTextureEditorPlugin, EditorPlugin);
+
+ CurveTextureEdit *curve_editor;
+ Ref<CurveTexture> curve_texture_ref;
+ EditorNode *editor;
+ ToolButton *curve_button;
+
+protected:
+ static void _bind_methods();
+ void _curve_changed();
+ void _undo_redo_curve_texture(const PoolVector<Vector2> &points);
+ void _curve_settings_changed();
+
+public:
+ virtual String get_name() const { return "CurveTexture"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_node);
+ virtual bool handles(Object *p_node) const;
+ virtual void make_visible(bool p_visible);
+
+ CurveTextureEditorPlugin(EditorNode *p_node);
+ ~CurveTextureEditorPlugin();
+};
+
+#endif // CURVE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/gradient_texture_editor_plugin.cpp b/editor/plugins/gradient_texture_editor_plugin.cpp
new file mode 100644
index 0000000000..1e82a1105a
--- /dev/null
+++ b/editor/plugins/gradient_texture_editor_plugin.cpp
@@ -0,0 +1,504 @@
+#include "gradient_texture_editor_plugin.h"
+
+#include "canvas_item_editor_plugin.h"
+#include "spatial_editor_plugin.h"
+
+#include "os/keyboard.h"
+#include "scene/resources/default_theme/theme_data.h"
+#define POINT_WIDTH 8
+
+GradientTextureEdit::GradientTextureEdit() {
+ grabbed = -1;
+ grabbing = false;
+ set_focus_mode(FOCUS_ALL);
+
+ popup = memnew(PopupPanel);
+ picker = memnew(ColorPicker);
+ popup->add_child(picker);
+
+ add_child(popup);
+
+ checker = Ref<ImageTexture>(memnew(ImageTexture));
+ checker->create_from_image(Image(checker_bg_png), ImageTexture::FLAG_REPEAT);
+}
+
+int GradientTextureEdit::_get_point_from_pos(int x) {
+ int result = -1;
+ int total_w = get_size().width - get_size().height - 3;
+ for (int i = 0; i < points.size(); i++) {
+ //Check if we clicked at point
+ if (ABS(x - points[i].offset * total_w + 1) < (POINT_WIDTH / 2 + 1)) {
+ result = i;
+ }
+ }
+ return result;
+}
+
+void GradientTextureEdit::_show_color_picker() {
+ if (grabbed == -1)
+ return;
+ Size2 ms = Size2(350, picker->get_combined_minimum_size().height + 10);
+ picker->set_pick_color(points[grabbed].color);
+ popup->set_pos(get_global_pos() - Vector2(ms.width - get_size().width, ms.height));
+ popup->set_size(ms);
+ popup->popup();
+}
+
+GradientTextureEdit::~GradientTextureEdit() {
+}
+
+void GradientTextureEdit::_gui_input(const InputEvent &p_event) {
+
+ if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode == KEY_DELETE && grabbed != -1) {
+
+ points.remove(grabbed);
+ grabbed = -1;
+ grabbing = false;
+ update();
+ emit_signal("ramp_changed");
+ accept_event();
+ }
+
+ //Show color picker on double click.
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.doubleclick && p_event.mouse_button.pressed) {
+ grabbed = _get_point_from_pos(p_event.mouse_button.x);
+ _show_color_picker();
+ accept_event();
+ }
+
+ //Delete point on right click
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 2 && p_event.mouse_button.pressed) {
+ grabbed = _get_point_from_pos(p_event.mouse_button.x);
+ if (grabbed != -1) {
+ points.remove(grabbed);
+ grabbed = -1;
+ grabbing = false;
+ update();
+ emit_signal("ramp_changed");
+ accept_event();
+ }
+ }
+
+ //Hold alt key to duplicate selected color
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed && p_event.key.mod.alt) {
+
+ int x = p_event.mouse_button.x;
+ grabbed = _get_point_from_pos(x);
+
+ if (grabbed != -1) {
+ int total_w = get_size().width - get_size().height - 3;
+ GradientTexture::Point newPoint = points[grabbed];
+ newPoint.offset = CLAMP(x / float(total_w), 0, 1);
+
+ points.push_back(newPoint);
+ points.sort();
+ for (int i = 0; i < points.size(); ++i) {
+ if (points[i].offset == newPoint.offset) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("ramp_changed");
+ update();
+ }
+ }
+
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed) {
+
+ update();
+ int x = p_event.mouse_button.x;
+ int total_w = get_size().width - get_size().height - 3;
+
+ //Check if color selector was clicked.
+ if (x > total_w + 3) {
+ _show_color_picker();
+ return;
+ }
+
+ grabbing = true;
+
+ grabbed = _get_point_from_pos(x);
+ //grab or select
+ if (grabbed != -1) {
+ return;
+ }
+
+ //insert
+ GradientTexture::Point newPoint;
+ newPoint.offset = CLAMP(x / float(total_w), 0, 1);
+
+ GradientTexture::Point prev;
+ GradientTexture::Point next;
+
+ int pos = -1;
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset < newPoint.offset)
+ pos = i;
+ }
+
+ if (pos == -1) {
+
+ prev.color = Color(0, 0, 0);
+ prev.offset = 0;
+ if (points.size()) {
+ next = points[0];
+ } else {
+ next.color = Color(1, 1, 1);
+ next.offset = 1.0;
+ }
+ } else {
+
+ if (pos == points.size() - 1) {
+ next.color = Color(1, 1, 1);
+ next.offset = 1.0;
+ } else {
+ next = points[pos + 1];
+ }
+ prev = points[pos];
+ }
+
+ newPoint.color = prev.color.linear_interpolate(next.color, (newPoint.offset - prev.offset) / (next.offset - prev.offset));
+
+ points.push_back(newPoint);
+ points.sort();
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset == newPoint.offset) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("ramp_changed");
+ }
+
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && !p_event.mouse_button.pressed) {
+
+ if (grabbing) {
+ grabbing = false;
+ emit_signal("ramp_changed");
+ }
+ update();
+ }
+
+ if (p_event.type == InputEvent::MOUSE_MOTION && grabbing) {
+
+ int total_w = get_size().width - get_size().height - 3;
+
+ int x = p_event.mouse_motion.x;
+ float newofs = CLAMP(x / float(total_w), 0, 1);
+
+ //Snap to nearest point if holding shift
+ if (p_event.key.mod.shift) {
+ float snap_treshhold = 0.03;
+ float smallest_ofs = snap_treshhold;
+ bool founded = false;
+ int nearest_point;
+ for (int i = 0; i < points.size(); ++i) {
+ if (i != grabbed) {
+ float temp_ofs = ABS(points[i].offset - newofs);
+ if (temp_ofs < smallest_ofs) {
+ smallest_ofs = temp_ofs;
+ nearest_point = i;
+ if (founded)
+ break;
+ founded = true;
+ }
+ }
+ }
+ if (founded) {
+ if (points[nearest_point].offset < newofs)
+ newofs = points[nearest_point].offset + 0.00001;
+ else
+ newofs = points[nearest_point].offset - 0.00001;
+ newofs = CLAMP(newofs, 0, 1);
+ }
+ }
+
+ bool valid = true;
+ for (int i = 0; i < points.size(); i++) {
+
+ if (points[i].offset == newofs && i != grabbed) {
+ valid = false;
+ }
+ }
+
+ if (!valid)
+ return;
+
+ points[grabbed].offset = newofs;
+
+ points.sort();
+ for (int i = 0; i < points.size(); i++) {
+ if (points[i].offset == newofs) {
+ grabbed = i;
+ break;
+ }
+ }
+
+ emit_signal("ramp_changed");
+
+ update();
+ }
+}
+
+void GradientTextureEdit::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ if (!picker->is_connected("color_changed", this, "_color_changed")) {
+ picker->connect("color_changed", this, "_color_changed");
+ }
+ }
+ if (p_what == NOTIFICATION_DRAW) {
+
+ int w = get_size().x;
+ int h = get_size().y;
+
+ if (w == 0 || h == 0)
+ return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size
+
+ int total_w = get_size().width - get_size().height - 3;
+
+ //Draw checker pattern for ramp
+ _draw_checker(0, 0, total_w, h);
+
+ //Draw color ramp
+ GradientTexture::Point prev;
+ prev.offset = 0;
+ if (points.size() == 0)
+ prev.color = Color(0, 0, 0); //Draw black rectangle if we have no points
+ else
+ prev.color = points[0].color; //Extend color of first point to the beginning.
+
+ for (int i = -1; i < points.size(); i++) {
+
+ GradientTexture::Point next;
+ //If there is no next point
+ if (i + 1 == points.size()) {
+ if (points.size() == 0)
+ next.color = Color(0, 0, 0); //Draw black rectangle if we have no points
+ else
+ next.color = points[i].color; //Extend color of last point to the end.
+ next.offset = 1;
+ } else {
+ next = points[i + 1];
+ }
+
+ if (prev.offset == next.offset) {
+ prev = next;
+ continue;
+ }
+
+ Vector<Vector2> points;
+ Vector<Color> colors;
+ points.push_back(Vector2(prev.offset * total_w, h));
+ points.push_back(Vector2(prev.offset * total_w, 0));
+ points.push_back(Vector2(next.offset * total_w, 0));
+ points.push_back(Vector2(next.offset * total_w, h));
+ colors.push_back(prev.color);
+ colors.push_back(prev.color);
+ colors.push_back(next.color);
+ colors.push_back(next.color);
+ draw_primitive(points, colors, Vector<Point2>());
+ prev = next;
+ }
+
+ //Draw point markers
+ for (int i = 0; i < points.size(); i++) {
+
+ Color col = i == grabbed ? Color(1, 0.0, 0.0, 0.9) : points[i].color.contrasted();
+ col.a = 0.9;
+
+ draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col);
+ draw_rect(Rect2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2, POINT_WIDTH, h / 2), Color(0.6, 0.6, 0.6, i == grabbed ? 0.9 : 0.4));
+ draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), col);
+ draw_line(Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col);
+ draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), col);
+ draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col);
+ }
+
+ //Draw "button" for color selector
+ _draw_checker(total_w + 3, 0, h, h);
+ if (grabbed != -1) {
+ //Draw with selection color
+ draw_rect(Rect2(total_w + 3, 0, h, h), points[grabbed].color);
+ } else {
+ //if no color selected draw grey color with 'X' on top.
+ draw_rect(Rect2(total_w + 3, 0, h, h), Color(0.5, 0.5, 0.5, 1));
+ draw_line(Vector2(total_w + 3, 0), Vector2(total_w + 3 + h, h), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(total_w + 3, h), Vector2(total_w + 3 + h, 0), Color(1, 1, 1, 0.6));
+ }
+
+ //Draw borders around color ramp if in focus
+ if (has_focus()) {
+
+ draw_line(Vector2(-1, -1), Vector2(total_w + 1, -1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(total_w + 1, -1), Vector2(total_w + 1, h + 1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(total_w + 1, h + 1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
+ }
+ }
+}
+
+void GradientTextureEdit::_draw_checker(int x, int y, int w, int h) {
+ //Draw it with polygon to insert UVs for scale
+ Vector<Vector2> backPoints;
+ backPoints.push_back(Vector2(x, y));
+ backPoints.push_back(Vector2(x, y + h));
+ backPoints.push_back(Vector2(x + w, y + h));
+ backPoints.push_back(Vector2(x + w, y));
+ Vector<Color> colorPoints;
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ Vector<Vector2> uvPoints;
+ //Draw checker pattern pixel-perfect and scale it by 2.
+ uvPoints.push_back(Vector2(x, y));
+ uvPoints.push_back(Vector2(x, y + h * .5f / checker->get_height()));
+ uvPoints.push_back(Vector2(x + w * .5f / checker->get_width(), y + h * .5f / checker->get_height()));
+ uvPoints.push_back(Vector2(x + w * .5f / checker->get_width(), y));
+ draw_polygon(backPoints, colorPoints, uvPoints, checker);
+}
+
+Size2 GradientTextureEdit::get_minimum_size() const {
+
+ return Vector2(0, 16);
+}
+
+void GradientTextureEdit::_color_changed(const Color &p_color) {
+
+ if (grabbed == -1)
+ return;
+ points[grabbed].color = p_color;
+ update();
+ emit_signal("ramp_changed");
+}
+
+void GradientTextureEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) {
+
+ ERR_FAIL_COND(p_offsets.size() != p_colors.size());
+ points.clear();
+ for (int i = 0; i < p_offsets.size(); i++) {
+ GradientTexture::Point p;
+ p.offset = p_offsets[i];
+ p.color = p_colors[i];
+ points.push_back(p);
+ }
+
+ points.sort();
+ update();
+}
+
+Vector<float> GradientTextureEdit::get_offsets() const {
+ Vector<float> ret;
+ for (int i = 0; i < points.size(); i++)
+ ret.push_back(points[i].offset);
+ return ret;
+}
+
+Vector<Color> GradientTextureEdit::get_colors() const {
+ Vector<Color> ret;
+ for (int i = 0; i < points.size(); i++)
+ ret.push_back(points[i].color);
+ return ret;
+}
+
+void GradientTextureEdit::set_points(Vector<GradientTexture::Point> &p_points) {
+ if (points.size() != p_points.size())
+ grabbed = -1;
+ points.clear();
+ points = p_points;
+}
+
+Vector<GradientTexture::Point> &GradientTextureEdit::get_points() {
+ return points;
+}
+
+void GradientTextureEdit::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_gui_input"), &GradientTextureEdit::_gui_input);
+ ClassDB::bind_method(D_METHOD("_color_changed"), &GradientTextureEdit::_color_changed);
+ ADD_SIGNAL(MethodInfo("ramp_changed"));
+}
+
+GradientTextureEditorPlugin::GradientTextureEditorPlugin(EditorNode *p_node) {
+
+ editor = p_node;
+ ramp_editor = memnew(GradientTextureEdit);
+
+ gradient_button = editor->add_bottom_panel_item("GradientTexture", ramp_editor);
+
+ gradient_button->hide();
+ ramp_editor->set_custom_minimum_size(Size2(100, 100 * EDSCALE));
+ ramp_editor->hide();
+ ramp_editor->connect("ramp_changed", this, "ramp_changed");
+}
+
+void GradientTextureEditorPlugin::edit(Object *p_object) {
+
+ GradientTexture *gradient_texture = p_object->cast_to<GradientTexture>();
+ if (!gradient_texture)
+ return;
+ gradient_texture_ref = Ref<GradientTexture>(gradient_texture);
+ ramp_editor->set_points(gradient_texture_ref->get_points());
+}
+
+bool GradientTextureEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_class("GradientTexture");
+}
+
+void GradientTextureEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+ gradient_button->show();
+ editor->make_bottom_panel_item_visible(ramp_editor);
+
+ } else {
+
+ gradient_button->hide();
+ if (ramp_editor->is_visible_in_tree())
+ editor->hide_bottom_panel();
+ }
+}
+
+void GradientTextureEditorPlugin::_ramp_changed() {
+
+ if (gradient_texture_ref.is_valid()) {
+
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ //Not sure if I should convert this data to PoolVector
+ Vector<float> new_offsets = ramp_editor->get_offsets();
+ Vector<Color> new_colors = ramp_editor->get_colors();
+ Vector<float> old_offsets = gradient_texture_ref->get_offsets();
+ Vector<Color> old_colors = gradient_texture_ref->get_colors();
+
+ if (old_offsets.size() != new_offsets.size())
+ ur->create_action(TTR("Add/Remove Color Ramp Point"));
+ else
+ ur->create_action(TTR("Modify Color Ramp"), UndoRedo::MERGE_ENDS);
+ ur->add_do_method(this, "undo_redo_gradient_texture", new_offsets, new_colors);
+ ur->add_undo_method(this, "undo_redo_gradient_texture", old_offsets, old_colors);
+ ur->commit_action();
+
+ //gradient_texture_ref->set_points(ramp_editor->get_points());
+ }
+}
+
+void GradientTextureEditorPlugin::_undo_redo_gradient_texture(const Vector<float> &offsets,
+ const Vector<Color> &colors) {
+
+ gradient_texture_ref->set_offsets(offsets);
+ gradient_texture_ref->set_colors(colors);
+ ramp_editor->set_points(gradient_texture_ref->get_points());
+ ramp_editor->update();
+}
+
+GradientTextureEditorPlugin::~GradientTextureEditorPlugin() {
+}
+
+void GradientTextureEditorPlugin::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("ramp_changed"), &GradientTextureEditorPlugin::_ramp_changed);
+ ClassDB::bind_method(D_METHOD("undo_redo_gradient_texture", "offsets", "colors"), &GradientTextureEditorPlugin::_undo_redo_gradient_texture);
+}
diff --git a/editor/plugins/gradient_texture_editor_plugin.h b/editor/plugins/gradient_texture_editor_plugin.h
new file mode 100644
index 0000000000..5af828f17c
--- /dev/null
+++ b/editor/plugins/gradient_texture_editor_plugin.h
@@ -0,0 +1,69 @@
+#ifndef GRADIENT_TEXTURE_EDITOR_PLUGIN_H
+#define GRADIENT_TEXTURE_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "scene/resources/texture.h"
+
+class GradientTextureEdit : public Control {
+
+ GDCLASS(GradientTextureEdit, Control);
+
+ PopupPanel *popup;
+ ColorPicker *picker;
+
+ Ref<ImageTexture> checker;
+
+ bool grabbing;
+ int grabbed;
+ Vector<GradientTexture::Point> points;
+
+ void _draw_checker(int x, int y, int w, int h);
+ void _color_changed(const Color &p_color);
+ int _get_point_from_pos(int x);
+ void _show_color_picker();
+
+protected:
+ void _gui_input(const InputEvent &p_event);
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors);
+ Vector<float> get_offsets() const;
+ Vector<Color> get_colors() const;
+ void set_points(Vector<GradientTexture::Point> &p_points);
+ Vector<GradientTexture::Point> &get_points();
+ virtual Size2 get_minimum_size() const;
+
+ GradientTextureEdit();
+ virtual ~GradientTextureEdit();
+};
+
+class GradientTextureEditorPlugin : public EditorPlugin {
+
+ GDCLASS(GradientTextureEditorPlugin, EditorPlugin);
+
+ bool _2d;
+ Ref<GradientTexture> gradient_texture_ref;
+ GradientTextureEdit *ramp_editor;
+ EditorNode *editor;
+ ToolButton *gradient_button;
+
+protected:
+ static void _bind_methods();
+ void _ramp_changed();
+ void _undo_redo_gradient_texture(const Vector<float> &offsets, const Vector<Color> &colors);
+
+public:
+ virtual String get_name() const { return "GradientTexture"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_node);
+ virtual bool handles(Object *p_node) const;
+ virtual void make_visible(bool p_visible);
+
+ GradientTextureEditorPlugin(EditorNode *p_node);
+ ~GradientTextureEditorPlugin();
+};
+
+#endif // GRADIENT_TEXTURE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp
index fd26674a0e..9624030246 100644
--- a/editor/plugins/particles_editor_plugin.cpp
+++ b/editor/plugins/particles_editor_plugin.cpp
@@ -27,30 +27,24 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if 0
#include "particles_editor_plugin.h"
#include "editor/plugins/spatial_editor_plugin.h"
#include "io/resource_loader.h"
-#include "servers/visual/particle_system_sw.h"
-
void ParticlesEditor::_node_removed(Node *p_node) {
- if(p_node==node) {
- node=NULL;
+ if (p_node == node) {
+ node = NULL;
hide();
}
-
}
-
-void ParticlesEditor::_resource_seleted(const String& p_res) {
+void ParticlesEditor::_resource_seleted(const String &p_res) {
//print_line("selected resource path: "+p_res);
}
-void ParticlesEditor::_node_selected(const NodePath& p_path){
-
+void ParticlesEditor::_node_selected(const NodePath &p_path) {
Node *sel = get_node(p_path);
if (!sel)
@@ -66,12 +60,11 @@ void ParticlesEditor::_node_selected(const NodePath& p_path){
geometry = vi->get_faces(VisualInstance::FACES_SOLID);
- if (geometry.size()==0) {
+ if (geometry.size() == 0) {
err_dialog->set_text(TTR("Node does not contain geometry (faces)."));
err_dialog->popup_centered_minsize();
return;
-
}
Transform geom_xform = node->get_global_transform().affine_inverse() * vi->get_global_transform();
@@ -79,20 +72,17 @@ void ParticlesEditor::_node_selected(const NodePath& p_path){
int gc = geometry.size();
PoolVector<Face3>::Write w = geometry.write();
-
- for(int i=0;i<gc;i++) {
- for(int j=0;j<3;j++) {
- w[i].vertex[j] = geom_xform.xform( w[i].vertex[j] );
+ for (int i = 0; i < gc; i++) {
+ for (int j = 0; j < 3; j++) {
+ w[i].vertex[j] = geom_xform.xform(w[i].vertex[j]);
}
}
-
w = PoolVector<Face3>::Write();
- emission_dialog->popup_centered(Size2(300,130));
+ emission_dialog->popup_centered(Size2(300, 130));
}
-
/*
void ParticlesEditor::_populate() {
@@ -112,74 +102,77 @@ void ParticlesEditor::_populate() {
void ParticlesEditor::_notification(int p_notification) {
- if (p_notification==NOTIFICATION_ENTER_TREE) {
- options->set_icon(options->get_popup()->get_icon("Particles","EditorIcons"));
-
+ if (p_notification == NOTIFICATION_ENTER_TREE) {
+ options->set_icon(options->get_popup()->get_icon("Particles", "EditorIcons"));
}
}
-
void ParticlesEditor::_menu_option(int p_option) {
-
- switch(p_option) {
+ switch (p_option) {
case MENU_OPTION_GENERATE_AABB: {
-
+#if 0
Transform globalizer = node->get_global_transform();
ParticleSystemSW pssw;
- for(int i=0;i<VS::PARTICLE_VAR_MAX;i++) {
+ for (int i = 0; i < VS::PARTICLE_VAR_MAX; i++) {
- pssw.particle_vars[i]=node->get_variable((Particles::Variable)i);
- pssw.particle_randomness[i]=node->get_randomness((Particles::Variable)i);
+ pssw.particle_vars[i] = node->get_variable((Particles::Variable)i);
+ pssw.particle_randomness[i] = node->get_randomness((Particles::Variable)i);
}
- pssw.emission_half_extents=node->get_emission_half_extents();
- pssw.emission_points=node->get_emission_points();
- pssw.emission_base_velocity=node->get_emission_base_velocity();
- pssw.amount=node->get_amount();
- pssw.gravity_normal=node->get_gravity_normal();
- pssw.emitting=true;
- pssw.height_from_velocity=node->has_height_from_velocity();
- pssw.color_phase_count=1;
-
+ pssw.emission_half_extents = node->get_emission_half_extents();
+ pssw.emission_points = node->get_emission_points();
+ pssw.emission_base_velocity = node->get_emission_base_velocity();
+ pssw.amount = node->get_amount();
+ pssw.gravity_normal = node->get_gravity_normal();
+ pssw.emitting = true;
+ pssw.height_from_velocity = node->has_height_from_velocity();
+ pssw.color_phase_count = 1;
ParticleSystemProcessSW pp;
- float delta=0.01;
- float lifetime=pssw.particle_vars[VS::PARTICLE_LIFETIME];
-
+ float delta = 0.01;
+ float lifetime = pssw.particle_vars[VS::PARTICLE_LIFETIME];
Transform localizer = globalizer.affine_inverse();
AABB aabb;
- for(float t=0;t<lifetime;t+=delta) {
+ for (float t = 0; t < lifetime; t += delta) {
- pp.process(&pssw,globalizer,delta);
- for(int i=0;i<pp.particle_data.size();i++) {
+ pp.process(&pssw, globalizer, delta);
+ for (int i = 0; i < pp.particle_data.size(); i++) {
Vector3 p = localizer.xform(pp.particle_data[i].pos);
- if (t==0 && i==0)
- aabb.pos=p;
+ if (t == 0 && i == 0)
+ aabb.pos = p;
else
aabb.expand_to(p);
}
}
- aabb.grow_by( aabb.get_longest_axis_size()*0.2);
+ aabb.grow_by(aabb.get_longest_axis_size() * 0.2);
node->set_visibility_aabb(aabb);
-
-
+#endif
} break;
case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH: {
-
+ Ref<ParticlesMaterial> material = node->get_process_material();
+ if (material.is_null()) {
+ EditorNode::get_singleton()->show_warning(TTR("A processor material of type 'ParticlesMaterial' is required."));
+ return;
+ }
emission_file_dialog->popup_centered_ratio();
} break;
case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: {
-/*
+ Ref<ParticlesMaterial> material = node->get_process_material();
+ if (material.is_null()) {
+ EditorNode::get_singleton()->show_warning(TTR("A processor material of type 'ParticlesMaterial' is required."));
+ return;
+ }
+ /*
Node *root = get_scene()->get_root_node();
ERR_FAIL_COND(!root);
EditorNode *en = root->cast_to<EditorNode>();
@@ -192,50 +185,50 @@ void ParticlesEditor::_menu_option(int p_option) {
}
}
-
void ParticlesEditor::edit(Particles *p_particles) {
- node=p_particles;
-
+ node = p_particles;
}
void ParticlesEditor::_generate_emission_points() {
/// hacer codigo aca
- PoolVector<Vector3> points;
+ PoolVector<float> points;
+ bool use_normals = emission_fill->get_selected() == 1;
+ PoolVector<float> normals;
- if (emission_fill->get_selected()==0) {
+ if (emission_fill->get_selected() < 2) {
- float area_accum=0;
- Map<float,int> triangle_area_map;
- print_line("geometry size: "+itos(geometry.size()));
+ float area_accum = 0;
+ Map<float, int> triangle_area_map;
+ print_line("geometry size: " + itos(geometry.size()));
- for(int i=0;i<geometry.size();i++) {
+ for (int i = 0; i < geometry.size(); i++) {
float area = geometry[i].get_area();
- if (area<CMP_EPSILON)
+ if (area < CMP_EPSILON)
continue;
- triangle_area_map[area_accum]=i;
- area_accum+=area;
+ triangle_area_map[area_accum] = i;
+ area_accum += area;
}
- if (!triangle_area_map.size() || area_accum==0) {
+ if (!triangle_area_map.size() || area_accum == 0) {
err_dialog->set_text(TTR("Faces contain no area!"));
err_dialog->popup_centered_minsize();
return;
}
- int emissor_count=emission_amount->get_val();
+ int emissor_count = emission_amount->get_value();
- for(int i=0;i<emissor_count;i++) {
+ for (int i = 0; i < emissor_count; i++) {
- float areapos = Math::random(0,area_accum);
+ float areapos = Math::random(0.0f, area_accum);
- Map<float,int>::Element *E = triangle_area_map.find_closest(areapos);
+ Map<float, int>::Element *E = triangle_area_map.find_closest(areapos);
ERR_FAIL_COND(!E)
int index = E->get();
- ERR_FAIL_INDEX(index,geometry.size());
+ ERR_FAIL_INDEX(index, geometry.size());
// ok FINALLY get face
Face3 face = geometry[index];
@@ -243,13 +236,22 @@ void ParticlesEditor::_generate_emission_points() {
Vector3 pos = face.get_random_point_inside();
- points.push_back(pos);
+ points.push_back(pos.x);
+ points.push_back(pos.y);
+ points.push_back(pos.z);
+
+ if (use_normals) {
+ Vector3 normal = face.get_plane().normal;
+ normals.push_back(normal.x);
+ normals.push_back(normal.y);
+ normals.push_back(normal.z);
+ }
}
} else {
int gcount = geometry.size();
- if (gcount==0) {
+ if (gcount == 0) {
err_dialog->set_text(TTR("No faces!"));
err_dialog->popup_centered_minsize();
@@ -258,32 +260,32 @@ void ParticlesEditor::_generate_emission_points() {
PoolVector<Face3>::Read r = geometry.read();
- AABB aabb;
+ Rect3 aabb;
- for(int i=0;i<gcount;i++) {
+ for (int i = 0; i < gcount; i++) {
- for(int j=0;j<3;j++) {
+ for (int j = 0; j < 3; j++) {
- if (i==0 && j==0)
- aabb.pos=r[i].vertex[j];
+ if (i == 0 && j == 0)
+ aabb.pos = r[i].vertex[j];
else
aabb.expand_to(r[i].vertex[j]);
}
}
- int emissor_count=emission_amount->get_val();
+ int emissor_count = emission_amount->get_value();
- for(int i=0;i<emissor_count;i++) {
+ for (int i = 0; i < emissor_count; i++) {
- int attempts=5;
+ int attempts = 5;
- for(int j=0;j<attempts;j++) {
+ for (int j = 0; j < attempts; j++) {
Vector3 dir;
- dir[Math::rand()%3]=1.0;
- Vector3 ofs = Vector3(1,1,1)-dir;
- ofs=(Vector3(1,1,1)-dir)*Vector3(Math::randf(),Math::randf(),Math::randf())*aabb.size;
- ofs+=aabb.pos;
+ dir[Math::rand() % 3] = 1.0;
+ Vector3 ofs = Vector3(1, 1, 1) - dir;
+ ofs = (Vector3(1, 1, 1) - dir) * Vector3(Math::randf(), Math::randf(), Math::randf()) * aabb.size;
+ ofs += aabb.pos;
Vector3 ofsv = ofs + aabb.size * dir;
@@ -291,135 +293,172 @@ void ParticlesEditor::_generate_emission_points() {
ofs -= dir;
ofsv += dir;
- float max=-1e7,min=1e7;
+ float max = -1e7, min = 1e7;
- for(int k=0;k<gcount;k++) {
+ for (int k = 0; k < gcount; k++) {
- const Face3& f3 = r[k];
+ const Face3 &f3 = r[k];
Vector3 res;
- if (f3.intersects_segment(ofs,ofsv,&res)) {
+ if (f3.intersects_segment(ofs, ofsv, &res)) {
- res-=ofs;
+ res -= ofs;
float d = dir.dot(res);
- if (d<min)
- min=d;
- if (d>max)
- max=d;
-
+ if (d < min)
+ min = d;
+ if (d > max)
+ max = d;
}
}
-
- if (max<min)
+ if (max < min)
continue; //lost attempt
- float val = min + (max-min)*Math::randf();
+ float val = min + (max - min) * Math::randf();
Vector3 point = ofs + dir * val;
- points.push_back(point);
+ points.push_back(point.x);
+ points.push_back(point.y);
+ points.push_back(point.z);
break;
}
}
}
- //print_line("point count: "+itos(points.size()));
- node->set_emission_points(points);
+ int point_count = points.size() / 3;
+
+ int w = 2048;
+ int h = (point_count / 2048) + 1;
+ PoolVector<uint8_t> point_img;
+ point_img.resize(w * h * 3 * sizeof(float));
+
+ {
+ PoolVector<uint8_t>::Write iw = point_img.write();
+ zeromem(iw.ptr(), w * h * 3 * sizeof(float));
+ PoolVector<float>::Read r = points.read();
+ copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3);
+ }
+
+ Image image(w, h, false, Image::FORMAT_RGBF, point_img);
+
+ Ref<ImageTexture> tex;
+ tex.instance();
+ tex->create_from_image(image, Texture::FLAG_FILTER);
+
+ Ref<ParticlesMaterial> material = node->get_process_material();
+ ERR_FAIL_COND(material.is_null());
+
+ if (use_normals) {
+
+ material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_DIRECTED_POINTS);
+ material->set_emission_point_count(point_count);
+ material->set_emission_point_texture(tex);
+
+ PoolVector<uint8_t> point_img2;
+ point_img2.resize(w * h * 3 * sizeof(float));
+
+ {
+ PoolVector<uint8_t>::Write iw = point_img2.write();
+ zeromem(iw.ptr(), w * h * 3 * sizeof(float));
+ PoolVector<float>::Read r = normals.read();
+ copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3);
+ }
+
+ Image image2(w, h, false, Image::FORMAT_RGBF, point_img2);
+
+ Ref<ImageTexture> tex2;
+ tex2.instance();
+ tex2->create_from_image(image2, Texture::FLAG_FILTER);
+
+ material->set_emission_normal_texture(tex2);
+ } else {
+
+ material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_POINTS);
+ material->set_emission_point_count(point_count);
+ material->set_emission_point_texture(tex);
+ }
+
+ //print_line("point count: "+itos(points.size()));
+ //node->set_emission_points(points);
}
void ParticlesEditor::_bind_methods() {
- ClassDB::bind_method("_menu_option",&ParticlesEditor::_menu_option);
- ClassDB::bind_method("_resource_seleted",&ParticlesEditor::_resource_seleted);
- ClassDB::bind_method("_node_selected",&ParticlesEditor::_node_selected);
- ClassDB::bind_method("_generate_emission_points",&ParticlesEditor::_generate_emission_points);
+ ClassDB::bind_method("_menu_option", &ParticlesEditor::_menu_option);
+ ClassDB::bind_method("_resource_seleted", &ParticlesEditor::_resource_seleted);
+ ClassDB::bind_method("_node_selected", &ParticlesEditor::_node_selected);
+ ClassDB::bind_method("_generate_emission_points", &ParticlesEditor::_generate_emission_points);
//ClassDB::bind_method("_populate",&ParticlesEditor::_populate);
-
}
ParticlesEditor::ParticlesEditor() {
- particles_editor_hb = memnew ( HBoxContainer );
+ particles_editor_hb = memnew(HBoxContainer);
SpatialEditor::get_singleton()->add_control_to_menu_panel(particles_editor_hb);
- options = memnew( MenuButton );
+ options = memnew(MenuButton);
particles_editor_hb->add_child(options);
particles_editor_hb->hide();
options->set_text("Particles");
- options->get_popup()->add_item(TTR("Generate AABB"),MENU_OPTION_GENERATE_AABB);
+ options->get_popup()->add_item(TTR("Generate AABB"), MENU_OPTION_GENERATE_AABB);
options->get_popup()->add_separator();
- options->get_popup()->add_item(TTR("Create Emitter From Mesh"),MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH);
- options->get_popup()->add_item(TTR("Create Emitter From Node"),MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE);
- options->get_popup()->add_item(TTR("Clear Emitter"),MENU_OPTION_CLEAR_EMISSION_VOLUME);
+ options->get_popup()->add_item(TTR("Create Emission Points From Mesh"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH);
+ options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE);
+ // options->get_popup()->add_item(TTR("Clear Emitter"), MENU_OPTION_CLEAR_EMISSION_VOLUME);
- options->get_popup()->connect("id_pressed", this,"_menu_option");
+ options->get_popup()->connect("id_pressed", this, "_menu_option");
- emission_dialog = memnew( ConfirmationDialog );
+ emission_dialog = memnew(ConfirmationDialog);
emission_dialog->set_title(TTR("Create Emitter"));
add_child(emission_dialog);
- Label *l = memnew(Label);
- l->set_pos(Point2(5,5));
- l->set_text(TTR("Emission Positions:"));
- emission_dialog->add_child(l);
-
+ VBoxContainer *emd_vb = memnew(VBoxContainer);
+ emission_dialog->add_child(emd_vb);
- emission_amount = memnew( SpinBox );
- emission_amount->set_anchor(MARGIN_RIGHT,ANCHOR_END);
- emission_amount->set_begin( Point2(20,23));
- emission_amount->set_end( Point2(5,25));
+ emission_amount = memnew(SpinBox);
emission_amount->set_min(1);
- emission_amount->set_max(65536);
- emission_amount->set_val(512);
- emission_dialog->add_child(emission_amount);
- emission_dialog->get_ok()->set_text(TTR("Create"));
- emission_dialog->connect("confirmed",this,"_generate_emission_points");
-
- l = memnew(Label);
- l->set_pos(Point2(5,50));
- l->set_text(TTR("Emission Fill:"));
- emission_dialog->add_child(l);
-
- emission_fill = memnew( OptionButton );
- emission_fill->set_anchor(MARGIN_RIGHT,ANCHOR_END);
- emission_fill->set_begin( Point2(20,70));
- emission_fill->set_end( Point2(5,75));
- emission_fill->add_item(TTR("Surface"));
+ emission_amount->set_max(100000);
+ emission_amount->set_value(512);
+ emd_vb->add_margin_child(TTR("Emission Points:"), emission_amount);
+
+ emission_fill = memnew(OptionButton);
+ emission_fill->add_item(TTR("Surface Points"));
+ emission_fill->add_item(TTR("Surface Points+Normal (Directed)"));
emission_fill->add_item(TTR("Volume"));
- emission_dialog->add_child(emission_fill);
+ emd_vb->add_margin_child(TTR("Emission Source: "), emission_fill);
+
+ emission_dialog->get_ok()->set_text(TTR("Create"));
+ emission_dialog->connect("confirmed", this, "_generate_emission_points");
- err_dialog = memnew( ConfirmationDialog );
+ err_dialog = memnew(ConfirmationDialog);
//err_dialog->get_cancel()->hide();
add_child(err_dialog);
-
- emission_file_dialog = memnew( EditorFileDialog );
+ emission_file_dialog = memnew(EditorFileDialog);
add_child(emission_file_dialog);
- emission_file_dialog->connect("file_selected",this,"_resource_seleted");
- emission_tree_dialog = memnew( SceneTreeDialog );
+ emission_file_dialog->connect("file_selected", this, "_resource_seleted");
+ emission_tree_dialog = memnew(SceneTreeDialog);
add_child(emission_tree_dialog);
- emission_tree_dialog->connect("selected",this,"_node_selected");
+ emission_tree_dialog->connect("selected", this, "_node_selected");
List<String> extensions;
- ResourceLoader::get_recognized_extensions_for_type("Mesh",&extensions);
+ ResourceLoader::get_recognized_extensions_for_type("Mesh", &extensions);
emission_file_dialog->clear_filters();
- for(int i=0;i<extensions.size();i++) {
+ for (int i = 0; i < extensions.size(); i++) {
- emission_file_dialog->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper());
+ emission_file_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
}
emission_file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
//options->set_anchor(MARGIN_LEFT,Control::ANCHOR_END);
//options->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END);
-
}
-
void ParticlesEditorPlugin::edit(Object *p_object) {
particles_editor->edit(p_object->cast_to<Particles>());
@@ -427,7 +466,7 @@ void ParticlesEditorPlugin::edit(Object *p_object) {
bool ParticlesEditorPlugin::handles(Object *p_object) const {
- return p_object->is_type("Particles");
+ return p_object->is_class("Particles");
}
void ParticlesEditorPlugin::make_visible(bool p_visible) {
@@ -440,21 +479,16 @@ void ParticlesEditorPlugin::make_visible(bool p_visible) {
particles_editor->hide();
particles_editor->edit(NULL);
}
-
}
ParticlesEditorPlugin::ParticlesEditorPlugin(EditorNode *p_node) {
- editor=p_node;
- particles_editor = memnew( ParticlesEditor );
+ editor = p_node;
+ particles_editor = memnew(ParticlesEditor);
editor->get_viewport()->add_child(particles_editor);
particles_editor->hide();
}
-
-ParticlesEditorPlugin::~ParticlesEditorPlugin()
-{
+ParticlesEditorPlugin::~ParticlesEditorPlugin() {
}
-
-#endif
diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h
index 420e20d641..b3394d879e 100644
--- a/editor/plugins/particles_editor_plugin.h
+++ b/editor/plugins/particles_editor_plugin.h
@@ -37,17 +37,16 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-#if 0
+
class ParticlesEditor : public Control {
- GDCLASS(ParticlesEditor, Control );
+ GDCLASS(ParticlesEditor, Control);
Panel *panel;
MenuButton *options;
HBoxContainer *particles_editor_hb;
Particles *node;
-
EditorFileDialog *emission_file_dialog;
SceneTreeDialog *emission_tree_dialog;
@@ -57,9 +56,6 @@ class ParticlesEditor : public Control {
SpinBox *emission_amount;
OptionButton *emission_fill;
-
-
-
enum Menu {
MENU_OPTION_GENERATE_AABB,
@@ -72,35 +68,33 @@ class ParticlesEditor : public Control {
PoolVector<Face3> geometry;
void _generate_emission_points();
- void _resource_seleted(const String& p_res);
- void _node_selected(const NodePath& p_path);
+ void _resource_seleted(const String &p_res);
+ void _node_selected(const NodePath &p_path);
void _menu_option(int);
void _populate();
-friend class ParticlesEditorPlugin;
+ friend class ParticlesEditorPlugin;
protected:
-
void _notification(int p_notification);
void _node_removed(Node *p_node);
static void _bind_methods();
-public:
+public:
void edit(Particles *p_particles);
ParticlesEditor();
};
class ParticlesEditorPlugin : public EditorPlugin {
- GDCLASS( ParticlesEditorPlugin, EditorPlugin );
+ GDCLASS(ParticlesEditorPlugin, EditorPlugin);
ParticlesEditor *particles_editor;
EditorNode *editor;
public:
-
virtual String get_name() const { return "Particles"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
@@ -109,8 +103,6 @@ public:
ParticlesEditorPlugin(EditorNode *p_node);
~ParticlesEditorPlugin();
-
};
#endif // PARTICLES_EDITOR_PLUGIN_H
-#endif
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index 0b3587bc5e..6fcda001ee 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -530,16 +530,16 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
editor=p_node;
singleton=this;
- path_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
- path_material->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.8) );
- path_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+ path_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
+ path_material->set_parameter( SpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.8) );
+ path_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
path_material->set_line_width(3);
path_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
path_material->set_flag(Material::FLAG_UNSHADED,true);
- path_thin_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));
- path_thin_material->set_parameter( FixedSpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.4) );
- path_thin_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true);
+ path_thin_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
+ path_thin_material->set_parameter( SpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.4) );
+ path_thin_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
path_thin_material->set_line_width(1);
path_thin_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
path_thin_material->set_flag(Material::FLAG_UNSHADED,true);
diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h
index 9d0f6eb9f2..131cf11ef8 100644
--- a/editor/plugins/path_editor_plugin.h
+++ b/editor/plugins/path_editor_plugin.h
@@ -78,8 +78,8 @@ public:
Path *get_edited_path() { return path; }
static PathEditorPlugin* singleton;
- Ref<FixedSpatialMaterial> path_material;
- Ref<FixedSpatialMaterial> path_thin_material;
+ Ref<SpatialMaterial> path_material;
+ Ref<SpatialMaterial> path_thin_material;
virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event);
//virtual bool forward_gui_input(const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 11dfb7b910..37782ed173 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -137,14 +137,35 @@ void ShaderTextEditor::_load_theme_settings() {
}*/
}
+void ShaderTextEditor::_check_shader_mode() {
+
+ String type = ShaderLanguage::get_shader_type(get_text_edit()->get_text());
+
+ print_line("type is: " + type);
+ Shader::Mode mode;
+
+ if (type == "canvas_item") {
+ mode = Shader::MODE_CANVAS_ITEM;
+ } else if (type == "particles") {
+ mode = Shader::MODE_PARTICLES;
+ } else {
+ mode = Shader::MODE_SPATIAL;
+ }
+
+ if (shader->get_mode() != mode) {
+ shader->set_code(get_text_edit()->get_text());
+ _load_theme_settings();
+ }
+}
+
void ShaderTextEditor::_code_complete_script(const String &p_code, List<String> *r_options) {
- print_line("code complete");
+ _check_shader_mode();
ShaderLanguage sl;
String calltip;
- Error err = sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), r_options, calltip);
+ Error err = sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip);
if (calltip != "") {
get_text_edit()->set_code_hint(calltip);
@@ -153,13 +174,15 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<String>
void ShaderTextEditor::_validate_script() {
+ _check_shader_mode();
+
String code = get_text_edit()->get_text();
//List<StringName> params;
//shader->get_param_list(&params);
ShaderLanguage sl;
- Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())));
+ Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types());
if (err != OK) {
String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index 4a56c14ecb..14caf4ab49 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -44,6 +44,8 @@ class ShaderTextEditor : public CodeTextEditor {
Ref<Shader> shader;
+ void _check_shader_mode();
+
protected:
static void _bind_methods();
virtual void _load_theme_settings();
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index d642a3c468..5e0901f9be 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -2329,12 +2329,12 @@ void SpatialEditor::_generate_selection_box() {
st->add_vertex(b);
}
- Ref<FixedSpatialMaterial> mat = memnew(FixedSpatialMaterial);
- mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+ Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
+ mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
mat->set_albedo(Color(1, 1, 1));
- mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
st->set_material(mat);
selection_box = st->commit();
}
@@ -2888,12 +2888,12 @@ void SpatialEditor::_init_indicators() {
{
indicator_mat.instance();
- indicator_mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- //indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP,true);
- indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- indicator_mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ indicator_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ //indicator_mat->set_flag(SpatialMaterial::FLAG_ONTOP,true);
+ indicator_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ indicator_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- indicator_mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ indicator_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
PoolVector<Color> grid_colors[3];
PoolVector<Vector3> grid_points[3];
@@ -2980,7 +2980,7 @@ void SpatialEditor::_init_indicators() {
cursor_points.push_back(Vector3(0, 0, -cs));
cursor_material.instance();
cursor_material->set_albedo(Color(0, 1, 1));
- cursor_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
+ cursor_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
Array d;
d.resize(VS::ARRAY_MAX);
@@ -3000,10 +3000,10 @@ void SpatialEditor::_init_indicators() {
float gizmo_alph = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_opacity");
- gizmo_hl = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));
- gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true);
- gizmo_hl->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ gizmo_hl = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ gizmo_hl->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ gizmo_hl->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ gizmo_hl->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
gizmo_hl->set_albedo(Color(1, 1, 1, gizmo_alph + 0.2f));
for (int i = 0; i < 3; i++) {
@@ -3011,10 +3011,10 @@ void SpatialEditor::_init_indicators() {
move_gizmo[i] = Ref<Mesh>(memnew(Mesh));
rotate_gizmo[i] = Ref<Mesh>(memnew(Mesh));
- Ref<FixedSpatialMaterial> mat = memnew(FixedSpatialMaterial);
- mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
- mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true);
- mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
+ Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
+ mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ mat->set_flag(SpatialMaterial::FLAG_ONTOP, true);
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
Color col;
col[i] = 1.0;
col.a = gizmo_alph;
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 734057dc90..0dedd6ce6d 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -323,8 +323,8 @@ private:
bool grid_enabled;
Ref<Mesh> move_gizmo[3], rotate_gizmo[3];
- Ref<FixedSpatialMaterial> gizmo_color[3];
- Ref<FixedSpatialMaterial> gizmo_hl;
+ Ref<SpatialMaterial> gizmo_color[3];
+ Ref<SpatialMaterial> gizmo_hl;
int over_gizmo_handle;
@@ -333,8 +333,8 @@ private:
RID indicators_instance;
RID cursor_mesh;
RID cursor_instance;
- Ref<FixedSpatialMaterial> indicator_mat;
- Ref<FixedSpatialMaterial> cursor_material;
+ Ref<SpatialMaterial> indicator_mat;
+ Ref<SpatialMaterial> cursor_material;
/*
struct Selected {
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 6dee151d99..2ae6f6a3d7 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -58,7 +58,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me
Sprite *mi = child->cast_to<Sprite>();
Ref<Texture> texture = mi->get_texture();
- Ref<CanvasItemMaterial> material = mi->get_material();
+ Ref<ShaderMaterial> material = mi->get_material();
if (texture.is_null())
continue;