material_editor_plugin.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. /*************************************************************************/
  2. /* material_editor_plugin.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. // FIXME: Disabled as (according to reduz) users were complaining that it gets in the way
  31. // Waiting for PropertyEditor rewrite (planned for 3.1) to be refactored.
  32. #include "material_editor_plugin.h"
  33. #include "scene/3d/particles.h"
  34. #if 0
  35. #include "scene/main/viewport.h"
  36. void MaterialEditor::_gui_input(InputEvent p_event) {
  37. }
  38. void MaterialEditor::_notification(int p_what) {
  39. if (p_what==NOTIFICATION_PHYSICS_PROCESS) {
  40. }
  41. if (p_what==NOTIFICATION_READY) {
  42. //get_scene()->connect("node_removed",this,"_node_removed");
  43. if (first_enter) {
  44. //it's in propertyeditor so.. could be moved around
  45. light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1","EditorIcons"));
  46. light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off","EditorIcons"));
  47. light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2","EditorIcons"));
  48. light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off","EditorIcons"));
  49. sphere_switch->set_normal_texture(get_icon("MaterialPreviewSphereOff","EditorIcons"));
  50. sphere_switch->set_pressed_texture(get_icon("MaterialPreviewSphere","EditorIcons"));
  51. box_switch->set_normal_texture(get_icon("MaterialPreviewCubeOff","EditorIcons"));
  52. box_switch->set_pressed_texture(get_icon("MaterialPreviewCube","EditorIcons"));
  53. first_enter=false;
  54. }
  55. }
  56. if (p_what==NOTIFICATION_DRAW) {
  57. Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons");
  58. Size2 size = get_size();
  59. draw_texture_rect(checkerboard,Rect2(Point2(),size),true);
  60. }
  61. }
  62. void MaterialEditor::edit(Ref<Material> p_material) {
  63. material=p_material;
  64. if (!material.is_null()) {
  65. sphere_mesh->surface_set_material(0,material);
  66. box_mesh->surface_set_material(0,material);
  67. } else {
  68. hide();
  69. }
  70. }
  71. void MaterialEditor::_button_pressed(Node* p_button) {
  72. if (p_button==light_1_switch) {
  73. light1->set_enabled(!light_1_switch->is_pressed());
  74. }
  75. if (p_button==light_2_switch) {
  76. light2->set_enabled(!light_2_switch->is_pressed());
  77. }
  78. if (p_button==box_switch) {
  79. box_instance->show();
  80. sphere_instance->hide();
  81. box_switch->set_pressed(true);
  82. sphere_switch->set_pressed(false);
  83. }
  84. if (p_button==sphere_switch) {
  85. box_instance->hide();
  86. sphere_instance->show();
  87. box_switch->set_pressed(false);
  88. sphere_switch->set_pressed(true);
  89. }
  90. }
  91. void MaterialEditor::_bind_methods() {
  92. ClassDB::bind_method(D_METHOD("_gui_input"),&MaterialEditor::_gui_input);
  93. ClassDB::bind_method(D_METHOD("_button_pressed"),&MaterialEditor::_button_pressed);
  94. }
  95. MaterialEditor::MaterialEditor() {
  96. viewport = memnew( Viewport );
  97. Ref<World> world;
  98. world.instance();
  99. viewport->set_world(world); //use own world
  100. add_child(viewport);
  101. viewport->set_disable_input(true);
  102. camera = memnew( Camera );
  103. camera->set_transform(Transform(Matrix3(),Vector3(0,0,3)));
  104. camera->set_perspective(45,0.1,10);
  105. viewport->add_child(camera);
  106. light1 = memnew( DirectionalLight );
  107. light1->set_transform(Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0)));
  108. viewport->add_child(light1);
  109. light2 = memnew( DirectionalLight );
  110. light2->set_transform(Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1)));
  111. light2->set_color(Light::COLOR_DIFFUSE,Color(0.7,0.7,0.7));
  112. light2->set_color(Light::COLOR_SPECULAR,Color(0.7,0.7,0.7));
  113. viewport->add_child(light2);
  114. sphere_instance = memnew( MeshInstance );
  115. viewport->add_child(sphere_instance);
  116. box_instance = memnew( MeshInstance );
  117. viewport->add_child(box_instance);
  118. Transform box_xform;
  119. box_xform.basis.rotate(Vector3(1,0,0),Math::deg2rad(25));
  120. box_xform.basis = box_xform.basis * Matrix3().rotated(Vector3(0,1,0),Math::deg2rad(25));
  121. box_xform.basis.scale(Vector3(0.8,0.8,0.8));
  122. box_instance->set_transform(box_xform);
  123. {
  124. sphere_mesh.instance();
  125. int lats=32;
  126. int lons=32;
  127. float radius=1.0;
  128. PoolVector<Vector3> vertices;
  129. PoolVector<Vector3> normals;
  130. PoolVector<Vector2> uvs;
  131. PoolVector<float> tangents;
  132. Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5);
  133. for(int i = 1; i <= lats; i++) {
  134. double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats);
  135. double z0 = Math::sin(lat0);
  136. double zr0 = Math::cos(lat0);
  137. double lat1 = Math_PI * (-0.5 + (double) i / lats);
  138. double z1 = Math::sin(lat1);
  139. double zr1 = Math::cos(lat1);
  140. for(int j = lons; j >= 1; j--) {
  141. double lng0 = 2 * Math_PI * (double) (j - 1) / lons;
  142. double x0 = Math::cos(lng0);
  143. double y0 = Math::sin(lng0);
  144. double lng1 = 2 * Math_PI * (double) (j) / lons;
  145. double x1 = Math::cos(lng1);
  146. double y1 = Math::sin(lng1);
  147. Vector3 v[4]={
  148. Vector3(x1 * zr0, z0, y1 *zr0),
  149. Vector3(x1 * zr1, z1, y1 *zr1),
  150. Vector3(x0 * zr1, z1, y0 *zr1),
  151. Vector3(x0 * zr0, z0, y0 *zr0)
  152. };
  153. #define ADD_POINT(m_idx) \
  154. normals.push_back(v[m_idx]); \
  155. vertices.push_back(v[m_idx] * radius); \
  156. { \
  157. Vector2 uv(Math::atan2(v[m_idx].x, v[m_idx].z), Math::atan2(-v[m_idx].y, v[m_idx].z)); \
  158. uv /= Math_PI; \
  159. uv *= 4.0; \
  160. uv = uv * 0.5 + Vector2(0.5, 0.5); \
  161. uvs.push_back(uv); \
  162. } \
  163. { \
  164. Vector3 t = tt.xform(v[m_idx]); \
  165. tangents.push_back(t.x); \
  166. tangents.push_back(t.y); \
  167. tangents.push_back(t.z); \
  168. tangents.push_back(1.0); \
  169. }
  170. ADD_POINT(0);
  171. ADD_POINT(1);
  172. ADD_POINT(2);
  173. ADD_POINT(2);
  174. ADD_POINT(3);
  175. ADD_POINT(0);
  176. }
  177. }
  178. Array arr;
  179. arr.resize(VS::ARRAY_MAX);
  180. arr[VS::ARRAY_VERTEX]=vertices;
  181. arr[VS::ARRAY_NORMAL]=normals;
  182. arr[VS::ARRAY_TANGENT]=tangents;
  183. arr[VS::ARRAY_TEX_UV]=uvs;
  184. sphere_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,arr);
  185. sphere_instance->set_mesh(sphere_mesh);
  186. }
  187. {
  188. box_mesh.instance();
  189. PoolVector<Vector3> vertices;
  190. PoolVector<Vector3> normals;
  191. PoolVector<float> tangents;
  192. PoolVector<Vector3> uvs;
  193. int vtx_idx=0;
  194. #define ADD_VTX(m_idx) \
  195. ; \
  196. vertices.push_back(face_points[m_idx]); \
  197. normals.push_back(normal_points[m_idx]); \
  198. tangents.push_back(normal_points[m_idx][1]); \
  199. tangents.push_back(normal_points[m_idx][2]); \
  200. tangents.push_back(normal_points[m_idx][0]); \
  201. tangents.push_back(1.0); \
  202. uvs.push_back(Vector3(uv_points[m_idx * 2 + 0], uv_points[m_idx * 2 + 1], 0)); \
  203. vtx_idx++;\
  204. for (int i=0;i<6;i++) {
  205. Vector3 face_points[4];
  206. Vector3 normal_points[4];
  207. float uv_points[8]={0,0,0,1,1,1,1,0};
  208. for (int j=0;j<4;j++) {
  209. float v[3];
  210. v[0]=1.0;
  211. v[1]=1-2*((j>>1)&1);
  212. v[2]=v[1]*(1-2*(j&1));
  213. for (int k=0;k<3;k++) {
  214. if (i<3)
  215. face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1);
  216. else
  217. face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1);
  218. }
  219. normal_points[j]=Vector3();
  220. normal_points[j][i%3]=(i>=3?-1:1);
  221. }
  222. //tri 1
  223. ADD_VTX(0);
  224. ADD_VTX(1);
  225. ADD_VTX(2);
  226. //tri 2
  227. ADD_VTX(2);
  228. ADD_VTX(3);
  229. ADD_VTX(0);
  230. }
  231. Array d;
  232. d.resize(VS::ARRAY_MAX);
  233. d[VisualServer::ARRAY_NORMAL]= normals ;
  234. d[VisualServer::ARRAY_TANGENT]= tangents ;
  235. d[VisualServer::ARRAY_TEX_UV]= uvs ;
  236. d[VisualServer::ARRAY_VERTEX]= vertices ;
  237. PoolVector<int> indices;
  238. indices.resize(vertices.size());
  239. for(int i=0;i<vertices.size();i++)
  240. indices.set(i,i);
  241. d[VisualServer::ARRAY_INDEX]=indices;
  242. box_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,d);
  243. box_instance->set_mesh(box_mesh);
  244. box_instance->hide();
  245. }
  246. set_custom_minimum_size(Size2(1,150)*EDSCALE);
  247. HBoxContainer *hb = memnew( HBoxContainer );
  248. add_child(hb);
  249. hb->set_anchors_and_margins_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 2);
  250. VBoxContainer *vb_shape = memnew( VBoxContainer );
  251. hb->add_child(vb_shape);
  252. sphere_switch = memnew( TextureButton );
  253. sphere_switch->set_toggle_mode(true);
  254. sphere_switch->set_pressed(true);
  255. vb_shape->add_child(sphere_switch);
  256. sphere_switch->connect("pressed",this,"_button_pressed",varray(sphere_switch));
  257. box_switch = memnew( TextureButton );
  258. box_switch->set_toggle_mode(true);
  259. box_switch->set_pressed(false);
  260. vb_shape->add_child(box_switch);
  261. box_switch->connect("pressed",this,"_button_pressed",varray(box_switch));
  262. hb->add_spacer();
  263. VBoxContainer *vb_light = memnew( VBoxContainer );
  264. hb->add_child(vb_light);
  265. light_1_switch = memnew( TextureButton );
  266. light_1_switch->set_toggle_mode(true);
  267. vb_light->add_child(light_1_switch);
  268. light_1_switch->connect("pressed",this,"_button_pressed",varray(light_1_switch));
  269. light_2_switch = memnew( TextureButton );
  270. light_2_switch->set_toggle_mode(true);
  271. vb_light->add_child(light_2_switch);
  272. light_2_switch->connect("pressed",this,"_button_pressed",varray(light_2_switch));
  273. first_enter=true;
  274. }
  275. void MaterialEditorPlugin::edit(Object *p_object) {
  276. Material * s = Object::cast_to<Material>(p_object);
  277. if (!s)
  278. return;
  279. material_editor->edit(Ref<Material>(s));
  280. }
  281. bool MaterialEditorPlugin::handles(Object *p_object) const {
  282. return p_object->is_type("Material");
  283. }
  284. void MaterialEditorPlugin::make_visible(bool p_visible) {
  285. if (p_visible) {
  286. material_editor->show();
  287. //material_editor->set_process(true);
  288. } else {
  289. material_editor->hide();
  290. //material_editor->set_process(false);
  291. }
  292. }
  293. MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) {
  294. editor=p_node;
  295. material_editor = memnew( MaterialEditor );
  296. add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,material_editor);
  297. material_editor->hide();
  298. }
  299. MaterialEditorPlugin::~MaterialEditorPlugin()
  300. {
  301. }
  302. #endif
  303. String SpatialMaterialConversionPlugin::converts_to() const {
  304. return "ShaderMaterial";
  305. }
  306. bool SpatialMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
  307. Ref<SpatialMaterial> mat = p_resource;
  308. return mat.is_valid();
  309. }
  310. Ref<Resource> SpatialMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) {
  311. Ref<SpatialMaterial> mat = p_resource;
  312. ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
  313. Ref<ShaderMaterial> smat;
  314. smat.instance();
  315. Ref<Shader> shader;
  316. shader.instance();
  317. String code = VS::get_singleton()->shader_get_code(mat->get_shader_rid());
  318. shader->set_code(code);
  319. smat->set_shader(shader);
  320. List<PropertyInfo> params;
  321. VS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), &params);
  322. for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) {
  323. // Texture parameter has to be treated specially since SpatialMaterial saved it
  324. // as RID but ShaderMaterial needs Texture itself
  325. Ref<Texture> texture = mat->get_texture_by_name(E->get().name);
  326. if (texture.is_valid()) {
  327. smat->set_shader_param(E->get().name, texture);
  328. } else {
  329. Variant value = VS::get_singleton()->material_get_param(mat->get_rid(), E->get().name);
  330. smat->set_shader_param(E->get().name, value);
  331. }
  332. }
  333. smat->set_render_priority(mat->get_render_priority());
  334. return smat;
  335. }
  336. String ParticlesMaterialConversionPlugin::converts_to() const {
  337. return "ShaderMaterial";
  338. }
  339. bool ParticlesMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
  340. Ref<ParticlesMaterial> mat = p_resource;
  341. return mat.is_valid();
  342. }
  343. Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) {
  344. Ref<ParticlesMaterial> mat = p_resource;
  345. ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
  346. Ref<ShaderMaterial> smat;
  347. smat.instance();
  348. Ref<Shader> shader;
  349. shader.instance();
  350. String code = VS::get_singleton()->shader_get_code(mat->get_shader_rid());
  351. shader->set_code(code);
  352. smat->set_shader(shader);
  353. List<PropertyInfo> params;
  354. VS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), &params);
  355. for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) {
  356. Variant value = VS::get_singleton()->material_get_param(mat->get_rid(), E->get().name);
  357. smat->set_shader_param(E->get().name, value);
  358. }
  359. smat->set_render_priority(mat->get_render_priority());
  360. return smat;
  361. }