1 #include "material_editor_plugin.h"
2 #include "scene/main/viewport.h"
3
_input_event(InputEvent p_event)4 void MaterialEditor::_input_event(InputEvent p_event) {
5 }
6
_notification(int p_what)7 void MaterialEditor::_notification(int p_what) {
8
9 if (p_what == NOTIFICATION_FIXED_PROCESS) {
10 }
11
12 if (p_what == NOTIFICATION_READY) {
13
14 //get_scene()->connect("node_removed",this,"_node_removed");
15
16 if (first_enter) {
17 //it's in propertyeditor so.. could be moved around
18
19 light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1", "EditorIcons"));
20 light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off", "EditorIcons"));
21 light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2", "EditorIcons"));
22 light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off", "EditorIcons"));
23
24 sphere_switch->set_normal_texture(get_icon("MaterialPreviewSphereOff", "EditorIcons"));
25 sphere_switch->set_pressed_texture(get_icon("MaterialPreviewSphere", "EditorIcons"));
26 box_switch->set_normal_texture(get_icon("MaterialPreviewCubeOff", "EditorIcons"));
27 box_switch->set_pressed_texture(get_icon("MaterialPreviewCube", "EditorIcons"));
28
29 first_enter = false;
30 }
31 }
32
33 if (p_what == NOTIFICATION_DRAW) {
34
35 Ref<Texture> checkerboard = get_icon("Checkerboard", "EditorIcons");
36 Size2 size = get_size();
37
38 draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
39 }
40 }
41
edit(Ref<Material> p_material)42 void MaterialEditor::edit(Ref<Material> p_material) {
43
44 material = p_material;
45
46 if (!material.is_null()) {
47 sphere_mesh->surface_set_material(0, material);
48 box_mesh->surface_set_material(0, material);
49 } else {
50
51 hide();
52 }
53 }
54
_button_pressed(Node * p_button)55 void MaterialEditor::_button_pressed(Node *p_button) {
56
57 if (p_button == light_1_switch) {
58 light1->set_enabled(!light_1_switch->is_pressed());
59 }
60
61 if (p_button == light_2_switch) {
62 light2->set_enabled(!light_2_switch->is_pressed());
63 }
64
65 if (p_button == box_switch) {
66 box_instance->show();
67 sphere_instance->hide();
68 box_switch->set_pressed(true);
69 sphere_switch->set_pressed(false);
70 }
71
72 if (p_button == sphere_switch) {
73 box_instance->hide();
74 sphere_instance->show();
75 box_switch->set_pressed(false);
76 sphere_switch->set_pressed(true);
77 }
78 }
79
_bind_methods()80 void MaterialEditor::_bind_methods() {
81
82 ObjectTypeDB::bind_method(_MD("_input_event"), &MaterialEditor::_input_event);
83 ObjectTypeDB::bind_method(_MD("_button_pressed"), &MaterialEditor::_button_pressed);
84 }
85
MaterialEditor()86 MaterialEditor::MaterialEditor() {
87
88 viewport = memnew(Viewport);
89 Ref<World> world;
90 world.instance();
91 viewport->set_world(world); //use own world
92 add_child(viewport);
93 viewport->set_disable_input(true);
94
95 camera = memnew(Camera);
96 camera->set_transform(Transform(Matrix3(), Vector3(0, 0, 3)));
97 camera->set_perspective(45, 0.1, 10);
98 viewport->add_child(camera);
99
100 light1 = memnew(DirectionalLight);
101 light1->set_transform(Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0)));
102 viewport->add_child(light1);
103
104 light2 = memnew(DirectionalLight);
105 light2->set_transform(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1)));
106 light2->set_color(Light::COLOR_DIFFUSE, Color(0.7, 0.7, 0.7));
107 light2->set_color(Light::COLOR_SPECULAR, Color(0.7, 0.7, 0.7));
108 viewport->add_child(light2);
109
110 sphere_instance = memnew(MeshInstance);
111 viewport->add_child(sphere_instance);
112
113 box_instance = memnew(MeshInstance);
114 viewport->add_child(box_instance);
115
116 Transform box_xform;
117 box_xform.basis.rotate(Vector3(1, 0, 0), Math::deg2rad(-25));
118 box_xform.basis = box_xform.basis * Matrix3().rotated(Vector3(0, 1, 0), Math::deg2rad(-25));
119 box_xform.basis.scale(Vector3(0.8, 0.8, 0.8));
120 box_instance->set_transform(box_xform);
121
122 {
123
124 sphere_mesh.instance();
125
126 int lats = 32;
127 int lons = 32;
128 float radius = 1.0;
129
130 DVector<Vector3> vertices;
131 DVector<Vector3> normals;
132 DVector<Vector2> uvs;
133 DVector<float> tangents;
134 Matrix3 tt = Matrix3(Vector3(0, 1, 0), Math_PI * 0.5);
135
136 for (int i = 1; i <= lats; i++) {
137 double lat0 = Math_PI * (-0.5 + (double)(i - 1) / lats);
138 double z0 = Math::sin(lat0);
139 double zr0 = Math::cos(lat0);
140
141 double lat1 = Math_PI * (-0.5 + (double)i / lats);
142 double z1 = Math::sin(lat1);
143 double zr1 = Math::cos(lat1);
144
145 for (int j = lons; j >= 1; j--) {
146
147 double lng0 = 2 * Math_PI * (double)(j - 1) / lons;
148 double x0 = Math::cos(lng0);
149 double y0 = Math::sin(lng0);
150
151 double lng1 = 2 * Math_PI * (double)(j) / lons;
152 double x1 = Math::cos(lng1);
153 double y1 = Math::sin(lng1);
154
155 Vector3 v[4] = {
156 Vector3(x1 * zr0, z0, y1 * zr0),
157 Vector3(x1 * zr1, z1, y1 * zr1),
158 Vector3(x0 * zr1, z1, y0 * zr1),
159 Vector3(x0 * zr0, z0, y0 * zr0)
160 };
161
162 #define ADD_POINT(m_idx) \
163 normals.push_back(v[m_idx]); \
164 vertices.push_back(v[m_idx] * radius); \
165 { \
166 Vector2 uv(Math::atan2(v[m_idx].x, v[m_idx].z), Math::atan2(-v[m_idx].y, v[m_idx].z)); \
167 uv /= Math_PI; \
168 uv *= 4.0; \
169 uv = uv * 0.5 + Vector2(0.5, 0.5); \
170 uvs.push_back(uv); \
171 } \
172 { \
173 Vector3 t = tt.xform(v[m_idx]); \
174 tangents.push_back(t.x); \
175 tangents.push_back(t.y); \
176 tangents.push_back(t.z); \
177 tangents.push_back(1.0); \
178 }
179
180 ADD_POINT(0);
181 ADD_POINT(1);
182 ADD_POINT(2);
183
184 ADD_POINT(2);
185 ADD_POINT(3);
186 ADD_POINT(0);
187 }
188 }
189
190 Array arr;
191 arr.resize(VS::ARRAY_MAX);
192 arr[VS::ARRAY_VERTEX] = vertices;
193 arr[VS::ARRAY_NORMAL] = normals;
194 arr[VS::ARRAY_TANGENT] = tangents;
195 arr[VS::ARRAY_TEX_UV] = uvs;
196
197 sphere_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES, arr);
198
199 sphere_instance->set_mesh(sphere_mesh);
200 }
201 {
202
203 box_mesh.instance();
204
205 DVector<Vector3> vertices;
206 DVector<Vector3> normals;
207 DVector<float> tangents;
208 DVector<Vector3> uvs;
209
210 int vtx_idx = 0;
211 #define ADD_VTX(m_idx) \
212 ; \
213 vertices.push_back(face_points[m_idx]); \
214 normals.push_back(normal_points[m_idx]); \
215 tangents.push_back(normal_points[m_idx][1]); \
216 tangents.push_back(normal_points[m_idx][2]); \
217 tangents.push_back(normal_points[m_idx][0]); \
218 tangents.push_back(1.0); \
219 uvs.push_back(Vector3(uv_points[m_idx * 2 + 0], uv_points[m_idx * 2 + 1], 0)); \
220 vtx_idx++;
221
222 for (int i = 0; i < 6; i++) {
223
224 Vector3 face_points[4];
225 Vector3 normal_points[4];
226 float uv_points[8] = { 0, 0, 0, 1, 1, 1, 1, 0 };
227
228 for (int j = 0; j < 4; j++) {
229
230 float v[3];
231 v[0] = 1.0;
232 v[1] = 1 - 2 * ((j >> 1) & 1);
233 v[2] = v[1] * (1 - 2 * (j & 1));
234
235 for (int k = 0; k < 3; k++) {
236
237 if (i < 3)
238 face_points[j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
239 else
240 face_points[3 - j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
241 }
242 normal_points[j] = Vector3();
243 normal_points[j][i % 3] = (i >= 3 ? -1 : 1);
244 }
245
246 //tri 1
247 ADD_VTX(0);
248 ADD_VTX(1);
249 ADD_VTX(2);
250 //tri 2
251 ADD_VTX(2);
252 ADD_VTX(3);
253 ADD_VTX(0);
254 }
255
256 Array d;
257 d.resize(VS::ARRAY_MAX);
258 d[VisualServer::ARRAY_NORMAL] = normals;
259 d[VisualServer::ARRAY_TANGENT] = tangents;
260 d[VisualServer::ARRAY_TEX_UV] = uvs;
261 d[VisualServer::ARRAY_VERTEX] = vertices;
262
263 DVector<int> indices;
264 indices.resize(vertices.size());
265 for (int i = 0; i < vertices.size(); i++)
266 indices.set(i, i);
267 d[VisualServer::ARRAY_INDEX] = indices;
268
269 box_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES, d);
270 box_instance->set_mesh(box_mesh);
271 box_instance->hide();
272 }
273
274 set_custom_minimum_size(Size2(1, 150) * EDSCALE);
275
276 HBoxContainer *hb = memnew(HBoxContainer);
277 add_child(hb);
278 hb->set_area_as_parent_rect(2);
279
280 VBoxContainer *vb_shape = memnew(VBoxContainer);
281 hb->add_child(vb_shape);
282
283 sphere_switch = memnew(TextureButton);
284 sphere_switch->set_toggle_mode(true);
285 sphere_switch->set_pressed(true);
286 vb_shape->add_child(sphere_switch);
287 sphere_switch->connect("pressed", this, "_button_pressed", varray(sphere_switch));
288
289 box_switch = memnew(TextureButton);
290 box_switch->set_toggle_mode(true);
291 box_switch->set_pressed(false);
292 vb_shape->add_child(box_switch);
293 box_switch->connect("pressed", this, "_button_pressed", varray(box_switch));
294
295 hb->add_spacer();
296
297 VBoxContainer *vb_light = memnew(VBoxContainer);
298 hb->add_child(vb_light);
299
300 light_1_switch = memnew(TextureButton);
301 light_1_switch->set_toggle_mode(true);
302 vb_light->add_child(light_1_switch);
303 light_1_switch->connect("pressed", this, "_button_pressed", varray(light_1_switch));
304
305 light_2_switch = memnew(TextureButton);
306 light_2_switch->set_toggle_mode(true);
307 vb_light->add_child(light_2_switch);
308 light_2_switch->connect("pressed", this, "_button_pressed", varray(light_2_switch));
309
310 first_enter = true;
311 }
312
edit(Object * p_object)313 void MaterialEditorPlugin::edit(Object *p_object) {
314
315 Material *s = p_object->cast_to<Material>();
316 if (!s)
317 return;
318
319 material_editor->edit(Ref<Material>(s));
320 }
321
handles(Object * p_object) const322 bool MaterialEditorPlugin::handles(Object *p_object) const {
323
324 return p_object->is_type("Material");
325 }
326
make_visible(bool p_visible)327 void MaterialEditorPlugin::make_visible(bool p_visible) {
328
329 if (p_visible) {
330 material_editor->show();
331 // material_editor->set_process(true);
332 } else {
333
334 material_editor->hide();
335 // material_editor->set_process(false);
336 }
337 }
338
MaterialEditorPlugin(EditorNode * p_node)339 MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) {
340
341 editor = p_node;
342 material_editor = memnew(MaterialEditor);
343 add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, material_editor);
344 material_editor->hide();
345 }
346
~MaterialEditorPlugin()347 MaterialEditorPlugin::~MaterialEditorPlugin() {
348 }
349