shader_graph.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*************************************************************************/
  2. /* shader_graph.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "shader_graph.h"
  30. #if 0
  31. struct _ConnectionKey {
  32. int node;
  33. int slot;
  34. _FORCE_INLINE_ _ConnectionKey(int p_node=0,int p_slot=0) { node=p_node; slot=p_slot; }
  35. _FORCE_INLINE_ bool operator<(const _ConnectionKey& p_other) const {
  36. if (node<p_other.node)
  37. return true;
  38. else if (node>p_other.node)
  39. return false;
  40. else
  41. return slot<p_other.slot;
  42. }
  43. };
  44. Error ShaderGraph::generate(ShaderCodeGenerator * p_generator) const {
  45. Map<int,Node>::Element *E = node_map.front();
  46. int i=0;
  47. while(E) {
  48. E->get().order=i++;
  49. E->get().out_valid=false;
  50. E->get().in_valid=false;
  51. E=E->next();
  52. }
  53. int worst_case=connections.size() * connections.size(); // worst bubble case
  54. int iterations=0;
  55. int swaps;
  56. do {
  57. swaps=0;
  58. const List<Connection>::Element *E=connections.front();
  59. while(E) {
  60. const Connection &c = E->get();
  61. const Node *src = &node_map[c.src_id];
  62. const Node *dst = &node_map[c.dst_id];
  63. if (src->order > dst->order) {
  64. SWAP(src->order, dst->order);
  65. swaps++;
  66. }
  67. E=E->next();
  68. }
  69. iterations++;
  70. } while (iterations<=worst_case && swaps>0);
  71. ERR_FAIL_COND_V( swaps != 0 , ERR_CYCLIC_LINK );
  72. //node array
  73. Vector<const Node*> nodes;
  74. nodes.resize(node_map.size());
  75. E = node_map.front();
  76. while(E) {
  77. ERR_FAIL_INDEX_V( E->get().order, nodes.size(), ERR_BUG);
  78. nodes[E->get().order]=&E->get();
  79. E=E->next();
  80. }
  81. //connection set
  82. Map<_ConnectionKey,int> in_connection_map;
  83. Map<_ConnectionKey,List<int> > out_connection_map;
  84. Map<_ConnectionKey,int> in_node_map;
  85. Map<_ConnectionKey,List<int> > out_node_map;
  86. const List<Connection>::Element *CE=connections.front();
  87. i=0;
  88. while(CE) {
  89. const Connection &c = CE->get();
  90. _ConnectionKey in_k;
  91. in_k.node=node_map[c.dst_id].order;
  92. in_k.slot=c.dst_slot;
  93. in_connection_map[in_k]=i;
  94. in_node_map[in_k]=node_map[c.src_id].order;
  95. _ConnectionKey out_k;
  96. out_k.node=node_map[c.src_id].order;
  97. out_k.slot=c.src_slot;
  98. if (!out_connection_map.has(out_k))
  99. out_connection_map[out_k]=List<int>();
  100. out_connection_map[out_k].push_back(i);
  101. if(!out_node_map.has(out_k))
  102. out_node_map[out_k]=List<int>();
  103. out_node_map[out_k].push_back(node_map[c.dst_id].order);
  104. i++;
  105. CE=CE->next();
  106. }
  107. // validate nodes if they are connected to an output
  108. for(int i=nodes.size()-1;i>=0;i--) {
  109. if (VisualServer::shader_get_output_count(nodes[i]->type)==0) {
  110. // an actual graph output
  111. _ConnectionKey in_k;
  112. in_k.node=nodes[i]->order;
  113. in_k.slot=0;
  114. if (in_node_map.has(in_k)) {
  115. nodes[i]->out_valid=true;
  116. }
  117. } else {
  118. // regular node
  119. bool valid=false;
  120. for(int j=0;j<VS::shader_get_output_count(nodes[i]->type);j++) {
  121. _ConnectionKey key(nodes[i]->order,j);
  122. if (out_node_map.has(key)) {
  123. for(List<int>::Element *CE=out_node_map[key].front();CE;CE=CE->next()) {
  124. int to_node=CE->get();
  125. ERR_CONTINUE(to_node<0 || to_node >=nodes.size());
  126. if (nodes[to_node]->out_valid) {
  127. valid=true;
  128. break;
  129. }
  130. }
  131. }
  132. if (valid)
  133. break;
  134. }
  135. nodes[i]->out_valid=valid;
  136. }
  137. }
  138. // validate nodes if they are connected to an input
  139. for(int i=0;i<nodes.size();i++) {
  140. if (VisualServer::shader_get_input_count(nodes[i]->type)==0) {
  141. // an actual graph input
  142. int out_count=VisualServer::shader_get_output_count(nodes[i]->type);
  143. for(int j=0;j<out_count;j++) {
  144. _ConnectionKey out_k;
  145. out_k.node=nodes[i]->order;
  146. out_k.slot=j;
  147. if (out_node_map.has(out_k)) {
  148. nodes[i]->in_valid=true;
  149. break;
  150. }
  151. }
  152. } else {
  153. // regular node
  154. // this is very important.. for a node to be valid, all its inputs need to be valid
  155. bool valid=true;
  156. for(int j=0;j<VS::shader_get_input_count(nodes[i]->type);j++) {
  157. bool in_valid=false;
  158. _ConnectionKey key(nodes[i]->order,j);
  159. if (in_node_map.has(key)) {
  160. int from_node=in_node_map[key];
  161. ERR_CONTINUE(from_node<0 || from_node>=nodes.size());
  162. if (nodes[from_node]->in_valid)
  163. in_valid=true;
  164. }
  165. if (!in_valid) {
  166. valid=false;
  167. break;
  168. }
  169. }
  170. nodes[i]->in_valid=valid;
  171. }
  172. }
  173. // write code
  174. p_generator->begin();
  175. for(int i=0;i<nodes.size();i++) {
  176. if (!nodes[i]->out_valid || !nodes[i]->in_valid) // valid in both ways
  177. continue; // skip node
  178. Vector<int> in_indices;
  179. in_indices.resize(VS::shader_get_input_count(nodes[i]->type));
  180. Vector<int> out_indices;
  181. Vector<int> out_slot_indices;
  182. for(int j=0;j<in_indices.size();j++) {
  183. _ConnectionKey key(nodes[i]->order,j);
  184. if (in_connection_map.has(key))
  185. in_indices[j]=in_connection_map[key];
  186. else
  187. in_indices[j]=-1;
  188. }
  189. for(int j=0;j<VS::shader_get_output_count(nodes[i]->type);j++) {
  190. _ConnectionKey key(nodes[i]->order,j);
  191. if (out_connection_map.has(key)) {
  192. for(List<int>::Element *CE=out_connection_map[key].front();CE;CE=CE->next()) {
  193. out_indices.push_back(CE->get());
  194. out_slot_indices.push_back(j);
  195. }
  196. }
  197. }
  198. Error err = p_generator->add_node(nodes[i]->type,i,nodes[i]->id,nodes[i]->param,in_indices,out_indices,out_slot_indices);
  199. ERR_FAIL_COND_V( err, err );
  200. }
  201. p_generator->end();
  202. return OK;
  203. }
  204. void ShaderGraph::node_add(VS::ShaderNodeType p_type,int p_id) {
  205. ERR_FAIL_COND( node_map.has(p_id ) );
  206. ERR_FAIL_INDEX( p_type, VS::NODE_TYPE_MAX );
  207. Node node;
  208. node.type=p_type;
  209. node.id=p_id;
  210. node.x=0;
  211. node.y=0;
  212. node_map[p_id]=node;
  213. }
  214. void ShaderGraph::node_set_pos(int p_id, int p_x,int p_y) {
  215. ERR_FAIL_COND(!node_map.has(p_id));
  216. node_map[p_id].x=p_x;
  217. node_map[p_id].y=p_y;
  218. }
  219. int ShaderGraph::node_get_pos_x(int p_id) const {
  220. ERR_FAIL_COND_V(!node_map.has(p_id),-1);
  221. return node_map[p_id].x;
  222. }
  223. int ShaderGraph::node_get_pos_y(int p_id) const {
  224. ERR_FAIL_COND_V(!node_map.has(p_id),-1);
  225. return node_map[p_id].y;
  226. }
  227. void ShaderGraph::node_remove(int p_id) {
  228. ERR_FAIL_COND(!node_map.has(p_id));
  229. //erase connections associated with node
  230. List<Connection>::Element *N,*E=connections.front();
  231. while(E) {
  232. N=E->next();
  233. const Connection &c = E->get();
  234. if (c.src_id==p_id || c.dst_id==p_id) {
  235. connections.erase(E);
  236. }
  237. E=N;
  238. }
  239. node_map.erase(p_id);
  240. }
  241. void ShaderGraph::node_change_type(int p_id, VS::ShaderNodeType p_type) {
  242. ERR_FAIL_COND(!node_map.has(p_id));
  243. node_map[p_id].type=p_type;
  244. node_map[p_id].param=Variant();
  245. }
  246. void ShaderGraph::node_set_param(int p_id, const Variant& p_value) {
  247. ERR_FAIL_COND(!node_map.has(p_id));
  248. node_map[p_id].param=p_value;
  249. }
  250. void ShaderGraph::get_node_list(List<int> *p_node_list) const {
  251. Map<int,Node>::Element *E = node_map.front();
  252. while(E) {
  253. p_node_list->push_back(E->key());
  254. E=E->next();
  255. }
  256. }
  257. VS::ShaderNodeType ShaderGraph::node_get_type(int p_id) const {
  258. ERR_FAIL_COND_V(!node_map.has(p_id),VS::NODE_TYPE_MAX);
  259. return node_map[p_id].type;
  260. }
  261. Variant ShaderGraph::node_get_param(int p_id) const {
  262. ERR_FAIL_COND_V(!node_map.has(p_id),Variant());
  263. return node_map[p_id].param;
  264. }
  265. Error ShaderGraph::connect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) {
  266. ERR_FAIL_COND_V(p_src_id==p_dst_id, ERR_INVALID_PARAMETER);
  267. ERR_FAIL_COND_V(!node_map.has(p_src_id), ERR_INVALID_PARAMETER);
  268. ERR_FAIL_COND_V(!node_map.has(p_dst_id), ERR_INVALID_PARAMETER);
  269. VisualServer::ShaderNodeType type_src=node_map[p_src_id].type;
  270. VisualServer::ShaderNodeType type_dst=node_map[p_dst_id].type;
  271. ERR_FAIL_INDEX_V( p_src_slot, VisualServer::shader_get_output_count(type_src), ERR_INVALID_PARAMETER );
  272. ERR_FAIL_INDEX_V( p_dst_slot, VisualServer::shader_get_input_count(type_dst), ERR_INVALID_PARAMETER );
  273. ERR_FAIL_COND_V(VisualServer::shader_is_output_vector(type_src,p_src_slot) != VisualServer::shader_is_input_vector(type_dst,p_dst_slot), ERR_INVALID_PARAMETER );
  274. List<Connection>::Element *E=connections.front();
  275. while(E) {
  276. const Connection &c = E->get();
  277. ERR_FAIL_COND_V(c.dst_slot==p_dst_slot && c.dst_id == p_dst_id, ERR_ALREADY_EXISTS);
  278. E=E->next();
  279. }
  280. Connection c;
  281. c.src_slot=p_src_slot;
  282. c.src_id=p_src_id;
  283. c.dst_slot=p_dst_slot;
  284. c.dst_id=p_dst_id;
  285. connections.push_back(c);
  286. return OK;
  287. }
  288. bool ShaderGraph::is_connected(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) const {
  289. const List<Connection>::Element *E=connections.front();
  290. while(E) {
  291. const Connection &c = E->get();
  292. if (c.dst_slot==p_dst_slot && c.dst_id == p_dst_id && c.src_slot==p_src_slot && c.src_id == p_src_id)
  293. return true;
  294. E=E->next();
  295. }
  296. return false;
  297. }
  298. void ShaderGraph::disconnect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) {
  299. List<Connection>::Element *N,*E=connections.front();
  300. while(E) {
  301. N=E->next();
  302. const Connection &c = E->get();
  303. if (c.src_slot==p_src_slot && c.src_id==p_src_id && c.dst_slot==p_dst_slot && c.dst_id == p_dst_id) {
  304. connections.erase(E);
  305. }
  306. E=N;
  307. }
  308. }
  309. void ShaderGraph::clear() {
  310. connections.clear();
  311. node_map.clear();
  312. }
  313. List<ShaderGraph::Connection> ShaderGraph::get_connection_list() const {
  314. return connections;
  315. }
  316. ShaderGraph::ShaderGraph() {
  317. }
  318. ShaderGraph::~ShaderGraph() {
  319. }
  320. #endif