*/}}

la_nodes_basic.c 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276
  1. #include "../la_5.h"
  2. extern LA MAIN;
  3. extern struct _tnsMain *T;
  4. laBaseNodeType LA_IDN_KEYBOARD;
  5. laBaseNodeType LA_IDN_MOUSE;
  6. laBaseNodeType LA_IDN_CONTROLLER;
  7. laBaseNodeType LA_IDN_VISUALIZER;
  8. laBaseNodeType LA_IDN_SPLIT;
  9. laBaseNodeType LA_IDN_SWITCH;
  10. laBaseNodeType LA_IDN_COMBINE;
  11. laBaseNodeType LA_IDN_VALUES;
  12. laBaseNodeType LA_IDN_MATRIX;
  13. laBaseNodeType LA_IDN_MATH;
  14. laBaseNodeType LA_IDN_SMALL_MATH;
  15. laBaseNodeType LA_IDN_MAPPER;
  16. laBaseNodeType LA_IDN_RANDOM;
  17. laBaseNodeType LA_IDN_VECTOR_MATH;
  18. laBaseNodeType LA_IDN_COMMENT;
  19. laBaseNodeType LA_IDN_RGB2OKHSL;
  20. laBaseNodeType LA_IDN_OKHSL2RGB;
  21. laPropContainer* LA_PC_IDN_GENERIC;
  22. laPropContainer* LA_PC_IDN_KEYBOARD;
  23. laPropContainer* LA_PC_IDN_MOUSE;
  24. laPropContainer* LA_PC_IDN_CONTROLLER;
  25. laPropContainer* LA_PC_IDN_VISUALIZER;
  26. laPropContainer* LA_PC_IDN_SPLIT;
  27. laPropContainer* LA_PC_IDN_SWITCH;
  28. laPropContainer* LA_PC_IDN_COMBINE;
  29. laPropContainer* LA_PC_IDN_VALUES;
  30. laPropContainer* LA_PC_IDN_MATRIX;
  31. laPropContainer* LA_PC_IDN_MATH;
  32. laPropContainer* LA_PC_IDN_SMALL_MATH;
  33. laPropContainer* LA_PC_IDN_MAPPER;
  34. laPropContainer* LA_PC_IDN_RANDOM;
  35. laPropContainer* LA_PC_IDN_VECTOR_MATH;
  36. laPropContainer* LA_PC_IDN_COMMENT;
  37. laPropContainer* LA_PC_IDN_RGB2OKHSL;
  38. laPropContainer* LA_PC_IDN_OKHSL2RGB;
  39. laNodeCategory* LA_NODE_CATEGORY_INPUT;
  40. laNodeCategory* LA_NODE_CATEGORY_MATH;
  41. laNodeCategory* LA_NODE_CATEGORY_ROUTE;
  42. laNodeCategory* LA_NODE_CATEGORY_AUX;
  43. laNodeCategory* LA_NODE_CATEGORY_DRIVER;
  44. laNodeCategory* LA_NODE_CATEGORY_COLOR;
  45. #define LA_IDN_CONTROLLER_RESET_SOCKET(ns)\
  46. {ns->IntVal[0]=0; ns->Out->DataType=LA_PROP_INT; ns->Offset=0; ns->Out->Data=&ns->IntVal;}
  47. void IDN_ControllerInit(laInputControllerNode* n, int NoCreate){
  48. if(NoCreate){return;}
  49. for(int i=0;i<8;i++){ n->Sockets[i].Out=laCreateOutSocket(n, "out", 0); n->Sockets[i].Parent=n; }
  50. strSafeSet(&n->Base.Name,"Controller Output");
  51. }
  52. void IDN_ControllerDestroy(laInputControllerNode* n){
  53. for(int i=0;i<8;i++){ laDestroyOutSocket(n->Sockets[i].Out); }
  54. strSafeDestroy(&n->Base.Name);
  55. }
  56. int IDN_ControllerVisit(laInputControllerNode* n, laListHandle* l){
  57. laController* c=la_FindControllerWithID(n->UserID);
  58. if(!c){ for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i]; LA_IDN_CONTROLLER_RESET_SOCKET(ns); } return LA_DAG_FLAG_PERM; }
  59. else{
  60. for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i];
  61. if(!ns->Which || !ns->Which->Ptr){ LA_IDN_CONTROLLER_RESET_SOCKET(ns); continue; }
  62. laPropContainer*pc=la_EnsureSubTarget(LA_PROP_CONTROLLER, c);
  63. laProp* p=la_PropLookup(&pc->Props, n->Sockets[i].Which->Ptr);
  64. if((!p)||(!p->Offset)||
  65. ((p->PropertyType!=LA_PROP_INT)&&(p->PropertyType!=LA_PROP_ENUM)&&
  66. (p->PropertyType!=(LA_PROP_INT|LA_PROP_ARRAY))&&(p->PropertyType!=(LA_PROP_ENUM|LA_PROP_ARRAY)))){ LA_IDN_CONTROLLER_RESET_SOCKET(ns); continue; }
  67. if(p->PropertyType==LA_PROP_INT){ ns->Out->DataType=LA_PROP_FLOAT; ns->Out->Data=&ns->RealVal; ns->Out->ArrLen=1; }
  68. elif(p->PropertyType==(LA_PROP_INT|LA_PROP_ARRAY)){ ns->Out->DataType=(LA_PROP_FLOAT|LA_PROP_ARRAY); ns->Out->Data=&ns->RealVal; ns->Out->ArrLen=p->Len; }
  69. elif(p->PropertyType==LA_PROP_ENUM){ ns->Out->DataType=LA_PROP_ENUM; ns->Out->Data=&ns->IntVal; ns->Out->ArrLen=1; }
  70. elif(p->PropertyType==(LA_PROP_ENUM|LA_PROP_ARRAY)){ ns->Out->DataType=(LA_PROP_ENUM|LA_PROP_ARRAY); ns->Out->Data=&ns->IntVal; ns->Out->ArrLen=p->Len; }
  71. ns->Offset=p->Offset;
  72. }
  73. }
  74. n->Base.Eval=LA_DAG_FLAG_PERM;
  75. lstAppendPointer(l, n);
  76. return LA_DAG_FLAG_PERM;
  77. }
  78. int IDN_ControllerEval(laInputControllerNode* n){
  79. laNotifyInstanceUsers(n);
  80. laController* c=la_FindControllerWithID(n->UserID); if(!c){
  81. for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i]; LA_IDN_CONTROLLER_RESET_SOCKET(ns); } return 1;
  82. }
  83. for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i];
  84. int *addr=((char*)c)+ns->Offset; char* addc=addr;
  85. if(ns->Out->DataType==LA_PROP_FLOAT){ ns->RealVal[0]=(real)(*addr)/32767.0; }
  86. if(ns->Out->DataType==(LA_PROP_FLOAT|LA_PROP_ARRAY)){ for(int a=0;a<ns->Out->ArrLen;a++) ns->RealVal[a]=((real)addr[a])/32767.0; }
  87. elif(ns->Out->DataType==LA_PROP_ENUM){ ns->IntVal[0]=(*addc); }
  88. elif(ns->Out->DataType==(LA_PROP_ENUM|LA_PROP_ARRAY)){ for(int a=0;a<ns->Out->ArrLen;a++) ns->IntVal[a]=addc[a]; }
  89. }
  90. return 1;
  91. }
  92. void laui_ControllerNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  93. laColumn* c=laFirstColumn(uil); laInputControllerNode*n=This->EndInstance;
  94. laColumn* cl,*cr;
  95. LA_BASE_NODE_HEADER(uil,c,This);
  96. laSplitColumn(uil,c,0.3); cl=laLeftColumn(c,0); cr=laRightColumn(c,0);
  97. laUiItem* b=laBeginRow(uil,c,0,0);
  98. laShowItem(uil,c,This,"base.name")->Expand=1;
  99. laShowItem(uil,c,This,"user_id");
  100. laEndRow(uil,b);
  101. char* buf[128],buf2[128];
  102. for(int i=0;i<8;i++){
  103. sprintf(buf,"out%d.which",i); laShowItem(uil,cl,This,buf);
  104. laUiItem* b=laBeginRow(uil,cr,0,0);
  105. sprintf(buf2,"out%d.out.data_type",i);
  106. laUiItem* b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,buf2),laIntExpression(LA_PROP_FLOAT)));{
  107. sprintf(buf,"out%d.axis",i); laShowItem(uil,cr,This,buf)->Expand=1;
  108. }laElse(uil,b2);{
  109. laUiItem* b3=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,buf2),laIntExpression(LA_PROP_FLOAT|LA_PROP_ARRAY)));{
  110. sprintf(buf,"out%d.axis2d",i); laUiItem* aui=laShowItem(uil,cr,This,buf);aui->Expand=1;aui->Flags|=LA_UI_FLAGS_TRANSPOSE;aui->Extra->HeightCoeff=1;
  111. }laElse(uil,b3);{
  112. sprintf(buf,"out%d.switch",i); laUiItem* sui=laShowItem(uil,cr,This,buf);sui->Expand=1;sui->Flags|=LA_UI_FLAGS_TRANSPOSE;
  113. }laEndCondition(uil,b3);
  114. }laEndCondition(uil,b2);
  115. sprintf(buf,"out%d.out",i); laShowNodeSocket(uil,cr,This,buf,0);
  116. laEndRow(uil,b);
  117. }
  118. }
  119. void IDN_InputVisualizeInit(laInputVisualizerNode* n, int NoCreate){
  120. if(NoCreate){return;}
  121. n->In=laCreateInSocket("IN", 0);
  122. strSafeSet(&n->Base.Name,"Input Visualizer");
  123. }
  124. void IDN_InputVisualizeDestroy(laInputVisualizerNode* n){
  125. laDestroyInSocket(n->In);
  126. strSafeDestroy(&n->Base.Name);
  127. }
  128. int IDN_InputVisualizeVisit(laInputVisualizerNode* n, laListHandle* l){
  129. n->Base.Eval=LA_DAG_FLAG_TEMP;
  130. if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* sn=n->In->Source->Parent;LA_VISIT_NODE(sn); }
  131. n->Base.Eval=LA_DAG_FLAG_PERM;
  132. lstAppendPointer(l, n);
  133. return LA_DAG_FLAG_PERM;
  134. }
  135. int IDN_InputVisualizerEval(laInputVisualizerNode* n){
  136. if(!n->In->Source) return 0;
  137. laNodeOutSocket* os=n->In->Source; int arrlen=1;
  138. switch(os->DataType){
  139. case LA_PROP_FLOAT|LA_PROP_ARRAY:
  140. case LA_PROP_FLOAT: if(os->ArrLen)arrlen=os->ArrLen; memcpy(n->RealVal,os->Data,sizeof(real)*arrlen); n->In->ArrLen=arrlen; break;
  141. case LA_PROP_ENUM|LA_PROP_ARRAY:
  142. case LA_PROP_ENUM: if(os->ArrLen)arrlen=os->ArrLen; memcpy(n->IntVal,os->Data,sizeof(int)*arrlen); n->In->ArrLen=arrlen; break;
  143. default: n->IntVal[0]=0; n->In->ArrLen=1; break;
  144. }
  145. n->In->DataType=os->DataType;
  146. laNotifyInstanceUsers(n);
  147. return 1;
  148. }
  149. void laui_InputVisualizeNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  150. laColumn* c=laFirstColumn(uil); laInputVisualizerNode*n=This->EndInstance;
  151. LA_BASE_NODE_HEADER(uil,c,This);
  152. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  153. laShowNodeSocket(uil,cl,This,"in",0);
  154. laUiItem* b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,"in.data_type"),laIntExpression(LA_PROP_FLOAT)));{
  155. laShowItem(uil,cr,This,"axis");
  156. }laElse(uil,b2);{
  157. laUiItem* b3=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,"in.data_type"),laIntExpression(LA_PROP_FLOAT|LA_PROP_ARRAY)));{
  158. laUiItem* aui=laShowItem(uil,cr,This,"axis2d");
  159. }laElse(uil,b3);{
  160. laUiItem* sui=laShowItem(uil,cr,This,"switch");
  161. }laEndCondition(uil,b3);
  162. }laEndCondition(uil,b2);
  163. }
  164. void IDN_SplitInit(laSplitNode* n, int NoCreate){
  165. if(NoCreate){return;}
  166. n->In=laCreateInSocket("in", 0); strSafeSet(&n->Base.Name,"Split");
  167. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->Out[i].Out=laCreateOutSocket(n,str,0); }
  168. }
  169. void IDN_SplitDestroy(laSplitNode* n){
  170. laDestroyInSocket(n->In); strSafeDestroy(&n->Base.Name);
  171. for(int i=0;i<8;i++){ laDestroyOutSocket(n->Out[i].Out); }
  172. }
  173. int IDN_SplitVisit(laSplitNode* n, laListHandle* l){
  174. LA_GUARD_THIS_NODE(n);
  175. if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* sn=n->In->Source->Parent; LA_VISIT_NODE(sn); }
  176. n->Base.Eval=LA_DAG_FLAG_PERM;
  177. lstAppendPointer(l, n);
  178. return LA_DAG_FLAG_PERM;
  179. }
  180. int IDN_SplitEval(laSplitNode* n){
  181. if(!n->In->Source) return 0;
  182. laNodeOutSocket* os=n->In->Source; int arrlen=1;
  183. switch(os->DataType){
  184. case LA_PROP_FLOAT|LA_PROP_ARRAY:
  185. case LA_PROP_FLOAT: if(os->ArrLen) n->ArrLen=os->ArrLen;
  186. for(int i=0;i<TNS_MIN2(n->ArrLen,8);i++){ n->Out[i].Out->DataType=LA_PROP_FLOAT; n->Out[i].Out->Data=&n->RealVal[i]; }
  187. memcpy(n->RealVal,os->Data,sizeof(real)*n->ArrLen); n->In->ArrLen=arrlen; break;
  188. case LA_PROP_ENUM|LA_PROP_ARRAY:
  189. case LA_PROP_ENUM: if(os->ArrLen) n->ArrLen=os->ArrLen;
  190. for(int i=0;i<TNS_MIN2(n->ArrLen,8);i++){ n->Out[i].Out->DataType=LA_PROP_ENUM; n->Out[i].Out->Data=&n->IntVal[i]; }
  191. memcpy(n->IntVal,os->Data,sizeof(int)*n->ArrLen); n->In->ArrLen=arrlen; break;
  192. default:
  193. for(int i=0;i<TNS_MIN2(n->ArrLen,8);i++){ n->Out[i].Out->DataType=LA_PROP_ENUM; n->Out[i].Out->Data=&n->IntVal[i]; }
  194. n->IntVal[0]=0; n->In->ArrLen=1; break;
  195. }
  196. n->In->DataType=os->DataType;
  197. return 1;
  198. }
  199. void laui_SplitNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  200. laColumn* c=laFirstColumn(uil); laSplitNode*n=This->EndInstance;
  201. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  202. LA_BASE_NODE_HEADER(uil,c,This);
  203. laUiItem* b=laBeginRow(uil,c,0,0);
  204. laShowNodeSocket(uil,c,This,"in",0);
  205. laShowItemFull(uil,c,This,"array_length",LA_WIDGET_INT_PLAIN,0,0,0);
  206. laShowLabel(uil,c,"🡲",0,0)->Expand=1;
  207. for(int i=0;i<8;i++){
  208. char* buf[128]; sprintf(buf,"out%d.out",i); laShowNodeSocket(uil,cr,This,buf,0);
  209. }
  210. laEndRow(uil,b);
  211. }
  212. void IDN_SwitchInit(laSwitchNode* n, int NoCreate){
  213. if(NoCreate){return;}
  214. n->SwitchIn=laCreateInSocket("sw in",0); n->Out=laCreateOutSocket(n,"out",0); strSafeSet(&n->Base.Name,"Switch");
  215. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->In[i].In=laCreateInSocket(n,str); }
  216. }
  217. void IDN_SwitchDestroy(laSwitchNode* n){
  218. laDestroyInSocket(n->SwitchIn); laDestroyOutSocket(n->Out); strSafeDestroy(&n->Base.Name);
  219. for(int i=0;i<8;i++){ laDestroyInSocket(n->In[i].In); }
  220. }
  221. int IDN_SwitchVisit(laSwitchNode* n, laListHandle* l){
  222. LA_GUARD_THIS_NODE(n);
  223. for(int i=0;i<8;i++){
  224. if(n->In[i].In->Source){ laBaseNode* sn=n->In[i].In->Source->Parent; LA_VISIT_NODE(sn); }
  225. }
  226. laBaseNode* sw=n->SwitchIn->Source?n->SwitchIn->Source->Parent:0; if(sw){ LA_VISIT_NODE(sw); }
  227. n->Base.Eval=LA_DAG_FLAG_PERM;
  228. lstAppendPointer(l, n);
  229. return LA_DAG_FLAG_PERM;
  230. }
  231. int IDN_SwitchEval(laSwitchNode* n){
  232. int sw=n->Switch;
  233. if(n->SwitchIn->Source){ laNodeOutSocket* os=n->SwitchIn->Source; int* id; real* fd;
  234. switch(os->DataType){
  235. case LA_PROP_ARRAY|LA_PROP_ENUM:
  236. id=os->Data; for(int i=0;i<os->ArrLen;i++){ if(id[i]){sw=i; break;} } break;
  237. case LA_PROP_ENUM: case LA_PROP_INT: case LA_PROP_INT|LA_PROP_ARRAY:
  238. id=os->Data; sw=*id; break;
  239. case LA_PROP_FLOAT: case LA_PROP_FLOAT|LA_PROP_ARRAY:
  240. fd=os->Data; sw=(int)(*fd); break;
  241. default: sw=0; break;
  242. }
  243. }
  244. TNS_CLAMP(sw,0,7);
  245. laSwitchNodeInSocket *is=&n->In[sw];
  246. if(is->In->Source){ n->Out->Data=is->In->Source->Data; n->Out->DataType=is->In->Source->DataType; n->Out->ArrLen=is->In->Source->ArrLen; }
  247. else{ n->Out->Data=&n->TempVal; n->Out->DataType=LA_PROP_FLOAT; n->Out->ArrLen=1; }
  248. return 1;
  249. }
  250. void laui_SwitchNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  251. laColumn* c=laFirstColumn(uil); laSwitchNode*n=This->EndInstance;
  252. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  253. LA_BASE_NODE_HEADER(uil,c,This);
  254. laUiItem* b=laBeginRow(uil,c,0,0);
  255. for(int i=0;i<8;i++){
  256. char* buf[128]; sprintf(buf,"in%d.in",i); laShowNodeSocket(uil,cr,This,buf,0);
  257. } laShowSeparator(uil,c)->Expand=1;
  258. laEndRow(uil,b);
  259. b=laBeginRow(uil,c,0,0);
  260. laShowItem(uil,c,This,"switch_in");
  261. laUiItem* b2=laOnConditionThat(uil,c,laNot(laPropExpression(This,"switch_in.source")));{
  262. laShowItem(uil,c,This,"switch");
  263. };laEndCondition(uil,b2);
  264. laShowSeparator(uil,c)->Expand=1;
  265. laShowNodeSocket(uil,c,This,"out",0);
  266. laEndRow(uil,b);
  267. }
  268. void IDN_CombineInit(laCombineNode* n, int NoCreate){
  269. if(!NoCreate){
  270. n->Out=laCreateOutSocket(n,"F",0);n->OutInt=laCreateOutSocket(n,"I",0);n->OutEnum=laCreateOutSocket(n,"E",0); strSafeSet(&n->Base.Name,"Combine");
  271. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->In[i].In=laCreateInSocket(n,str); }
  272. }
  273. n->Out->Data=n->Values; n->OutInt->Data=n->ValuesI; n->OutEnum->Data=n->ValuesI;
  274. n->Out->DataType=LA_PROP_FLOAT|LA_PROP_ARRAY; n->OutInt->DataType=LA_PROP_INT|LA_PROP_ARRAY; n->OutEnum->DataType=LA_PROP_ENUM|LA_PROP_ARRAY;
  275. }
  276. void IDN_CombineDestroy(laCombineNode* n){
  277. laDestroyOutSocket(n->Out);laDestroyOutSocket(n->OutInt);laDestroyOutSocket(n->OutEnum); strSafeDestroy(&n->Base.Name);
  278. for(int i=0;i<8;i++){ laDestroyInSocket(n->In[i].In); }
  279. }
  280. int IDN_CombineVisit(laCombineNode* n, laListHandle* l){
  281. LA_GUARD_THIS_NODE(n);
  282. for(int i=0;i<8;i++){ if(LA_SRC_AND_PARENT(n->In[i].In)){ laBaseNode* sn=n->In[i].In->Source->Parent; LA_VISIT_NODE(sn); } }
  283. n->Base.Eval=LA_DAG_FLAG_PERM;
  284. lstAppendPointer(l, n);
  285. return LA_DAG_FLAG_PERM;
  286. }
  287. int IDN_CombineEval(laCombineNode* n){
  288. int maxlen=0;
  289. for(int i=0;i<8;i++){ laNodeInSocket *is=n->In[i].In;
  290. if(LA_SRC_AND_PARENT(is)){
  291. if((is->Source->DataType&LA_PROP_FLOAT) && is->Source->Data){ n->Values[i]=*((real*)is->Source->Data); }
  292. elif((is->Source->DataType&LA_PROP_INT) && is->Source->Data){ n->Values[i]=*((int*)is->Source->Data); }
  293. elif((is->Source->DataType&LA_PROP_ENUM) && is->Source->Data){ n->Values[i]=*((int*)is->Source->Data); }
  294. else n->Values[i]=0;
  295. maxlen=i+1;
  296. }
  297. else n->Values[i]=0;
  298. n->ValuesI[i]=n->Values[i];
  299. }
  300. n->Out->ArrLen=n->OutInt->ArrLen=n->OutEnum->ArrLen=maxlen;
  301. return 1;
  302. }
  303. void laui_CombineNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  304. laColumn* c=laFirstColumn(uil); laCombineNode*n=This->EndInstance;
  305. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  306. LA_BASE_NODE_HEADER(uil,c,This);
  307. laUiItem* b=laBeginRow(uil,c,0,0);
  308. for(int i=0;i<8;i++){
  309. char* buf[128]; sprintf(buf,"in%d.in",i); laShowNodeSocket(uil,cr,This,buf,0);
  310. } laShowSeparator(uil,c)->Expand=1;
  311. laEndRow(uil,b);
  312. b=laBeginRow(uil,c,0,0);
  313. laUiItem* lu=laShowLabel(uil,c,"Combine 🡲",0,0); lu->Expand=1; lu->Flags|=LA_TEXT_ALIGN_RIGHT;
  314. laShowNodeSocket(uil,c,This,"out_enum",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  315. laShowNodeSocket(uil,c,This,"out_int",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  316. laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  317. laEndRow(uil,b);
  318. }
  319. void IDN_ValuesInit(laValuesNode* n, int NoCreate){
  320. if(NoCreate){return;}
  321. strSafeSet(&n->Base.Name,"Values");
  322. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->Out[i].Out=laCreateOutSocket(n,str,0); }
  323. }
  324. void IDN_ValuesDestroy(laValuesNode* n){
  325. strSafeDestroy(&n->Base.Name);
  326. for(int i=0;i<8;i++){ laDestroyOutSocket(n->Out[i].Out); }
  327. }
  328. int IDN_ValuesVisit(laValuesNode* n, laListHandle* l){
  329. LA_GUARD_THIS_NODE(n);
  330. n->Base.Eval=LA_DAG_FLAG_PERM;
  331. lstAppendPointer(l, n);
  332. return LA_DAG_FLAG_PERM;
  333. }
  334. int IDN_ValuesEval(laValuesNode* n){
  335. for(int i=0;i<8;i++){ laNodeOutSocket *is=n->Out[i].Out;
  336. if(n->Modes[i]==LA_VALUES_NODE_FLOAT){ is->Data=&n->Values[i]; is->DataType=LA_PROP_FLOAT; }
  337. if(n->Modes[i]==LA_VALUES_NODE_INT){ is->Data=&n->ValuesI[i]; is->DataType=LA_PROP_INT; }
  338. if(n->Modes[i]==LA_VALUES_NODE_ENUM){ is->Data=&n->ValuesE[i]; is->DataType=LA_PROP_ENUM; }
  339. }
  340. return 1;
  341. }
  342. void laui_ValuesNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  343. laColumn* c=laFirstColumn(uil); laValuesNode*n=This->EndInstance;
  344. laUiItem*b,*b2;
  345. LA_BASE_NODE_HEADER(uil,c,This);
  346. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  347. for(int i=0;i<8;i++){
  348. char* bufm[32]; sprintf(bufm,"mode%d",i); laShowItem(uil,cl,This,bufm);
  349. b=laBeginRow(uil,cr,0,0);
  350. b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,bufm),laIntExpression(LA_VALUES_NODE_FLOAT)));{
  351. char* buf[32]; sprintf(buf,"value%d",i); laShowItem(uil,cr,This,buf)->Expand=1;
  352. }laEndCondition(uil,b2);
  353. b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,bufm),laIntExpression(LA_VALUES_NODE_INT)));{
  354. char* buf[32]; sprintf(buf,"valuei%d",i); laShowItem(uil,cr,This,buf)->Expand=1;
  355. }laEndCondition(uil,b2);
  356. b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,bufm),laIntExpression(LA_VALUES_NODE_ENUM)));{
  357. char* buf[32]; sprintf(buf,"valuee%d",i); laUiItem* eui=laShowItem(uil,cr,This,buf); eui->Expand=1; eui->Flags|=LA_UI_FLAGS_HIGHLIGHT;
  358. }laEndCondition(uil,b2);
  359. sprintf(bufm,"out%d.out",i); laShowNodeSocket(uil,cr,This,bufm,0);
  360. laEndRow(uil,b);
  361. }
  362. }
  363. void IDN_MatrixInit(laMatrixNode* n, int NoCreate){
  364. if(!NoCreate){
  365. strSafeSet(&n->Base.Name,"Matrix");
  366. n->InL=laCreateInSocket("l",0); n->InR=laCreateInSocket("r",0); n->Out=laCreateOutSocket(n,"MAT",LA_PROP_FLOAT|LA_PROP_ARRAY);
  367. }
  368. n->Out->ArrLen=16; n->Out->Data=n->Mat;
  369. }
  370. void IDN_MatrixDestroy(laMatrixNode* n){
  371. strSafeDestroy(&n->Base.Name);
  372. laDestroyInSocket(n->InL); laDestroyInSocket(n->InR); laDestroyOutSocket(n->Out);
  373. }
  374. int IDN_MatrixVisit(laMatrixNode* n, laListHandle* l){
  375. LA_GUARD_THIS_NODE(n);
  376. if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
  377. if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn); }
  378. n->Base.Eval=LA_DAG_FLAG_PERM;
  379. lstAppendPointer(l, n);
  380. return LA_DAG_FLAG_PERM;
  381. }
  382. int IDN_MatrixEval(laMatrixNode* n){
  383. int hasl=LA_SRC_AND_PARENT(n->InL),hasr=LA_SRC_AND_PARENT(n->InR);
  384. if((!hasl) && (!hasr)){ tnsLoadIdentity44d(n->Mat); return 0; }
  385. if(hasl&&((n->InL->Source->DataType!=(LA_PROP_FLOAT|LA_PROP_ARRAY))||n->InL->Source->ArrLen!=16)){tnsLoadIdentity44d(n->Mat); return 0;}
  386. if(hasr&&((n->InR->Source->DataType!=(LA_PROP_FLOAT|LA_PROP_ARRAY))||n->InR->Source->ArrLen!=16)){tnsLoadIdentity44d(n->Mat); return 0;}
  387. if(n->Operation==LA_MATRIX_NODE_OP_INV){
  388. real* mat; if(hasl)mat=n->InL->Source->Data;else mat=n->InR->Source->Data;
  389. tnsInverse44d(n->Mat, mat);
  390. }else{
  391. if(!hasl) { memcpy(n->Mat,n->InR->Source->Data,sizeof(tnsMatrix44d)); }
  392. elif(!hasr) { memcpy(n->Mat,n->InL->Source->Data,sizeof(tnsMatrix44d)); }
  393. else{
  394. tnsMultiply44d(n->Mat,n->InL->Source->Data,n->InR->Source->Data);
  395. }
  396. }
  397. return 1;
  398. }
  399. void laui_MatrixNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  400. laColumn* c=laFirstColumn(uil); laMatrixNode*n=This->EndInstance;
  401. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  402. laUiItem*b,*b2;
  403. LA_BASE_NODE_HEADER(uil,c,This);
  404. b=laBeginRow(uil,c,0,0);
  405. laShowNodeSocket(uil,c,This,"in_l",0); laShowNodeSocket(uil,c,This,"in_r",0); laShowItem(uil,c,This,"operation");
  406. laShowSeparator(uil,c)->Expand=1; laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  407. laEndRow(uil,b);
  408. }
  409. void IDN_MathInit(laMathNode* n, int NoCreate){
  410. if(!NoCreate){
  411. strSafeSet(&n->Base.Name,"Math");
  412. n->InL=laCreateInSocket("l",0); n->InR=laCreateInSocket("r",0);
  413. n->Out=laCreateOutSocket(n,"F",LA_PROP_FLOAT); n->OutInt=laCreateOutSocket(n,"I",LA_PROP_INT);
  414. }
  415. n->Out->Data=&n->Value; n->OutInt->Data=&n->ValueI;
  416. }
  417. void IDN_MathDestroy(laMathNode* n){
  418. strSafeDestroy(&n->Base.Name); laDestroyInSocket(n->InL); laDestroyInSocket(n->InR); laDestroyOutSocket(n->Out); laDestroyOutSocket(n->OutInt);
  419. }
  420. int IDN_MathVisit(laMathNode* n, laListHandle* l){
  421. LA_GUARD_THIS_NODE(n);
  422. if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
  423. if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn); }
  424. n->Base.Eval=LA_DAG_FLAG_PERM;
  425. lstAppendPointer(l, n);
  426. return LA_DAG_FLAG_PERM;
  427. }
  428. #define LA_GET_SRC_AS_FLOAT(var, socket)\
  429. {if(socket->Source->DataType&LA_PROP_FLOAT) var=*((real*)socket->Source->Data);\
  430. if(socket->Source->DataType&(LA_PROP_INT|LA_PROP_ENUM)) var=*((int*)socket->Source->Data);}
  431. int IDN_MathEval(laMathNode* n){
  432. real vl=n->ValueL;real vr=n->ValueR;
  433. int hasl=LA_SRC_AND_PARENT(n->InL),hasr=LA_SRC_AND_PARENT(n->InR);
  434. if(hasl){ LA_GET_SRC_AS_FLOAT(vl,n->InL) } if(hasr){ LA_GET_SRC_AS_FLOAT(vr,n->InR) }
  435. switch(n->Operation){
  436. case LA_MATH_NODE_OP_ADD: default: n->Value=vl+vr; break;
  437. case LA_MATH_NODE_OP_SUB: n->Value=vl-vr; break;
  438. case LA_MATH_NODE_OP_MUL: n->Value=vl*vr; break;
  439. case LA_MATH_NODE_OP_DIV: if(vr)n->Value=vl/vr;else n->Value=0; break;
  440. case LA_MATH_NODE_OP_POW: n->Value=pow(vl,vr); break;
  441. case LA_MATH_NODE_OP_LOG: n->Value=log2(vl)/log2(vr); break;
  442. case LA_MATH_NODE_OP_SIN: n->Value=sin(vl); break;
  443. case LA_MATH_NODE_OP_COS: n->Value=cos(vl); break;
  444. case LA_MATH_NODE_OP_TAN: n->Value=tan(vl); break;
  445. case LA_MATH_NODE_OP_ASIN: n->Value=asin(vl); break;
  446. case LA_MATH_NODE_OP_ACOS: n->Value=acos(vl); break;
  447. case LA_MATH_NODE_OP_ATAN: n->Value=atan(vl); break;
  448. case LA_MATH_NODE_OP_ATAN2: n->Value=atan2(vl,vr); break;
  449. case LA_MATH_NODE_OP_MOD: n->Value=fmod(vl,vr); break;
  450. }
  451. n->ValueI=(int)n->Value;
  452. return 1;
  453. }
  454. void laui_MathNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  455. laColumn* c=laFirstColumn(uil); laMathNode*n=This->EndInstance;
  456. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  457. laUiItem*b,*b2;
  458. LA_BASE_NODE_HEADER(uil,c,This);
  459. b=laBeginRow(uil,c,0,0);
  460. laShowNodeSocket(uil,c,This,"in_l",0); b=laOnConditionThat(uil,c,laNot(laPropExpression(This,"in_l.source")));{ laShowItem(uil,c,This,"vl"); }laEndCondition(uil,b);
  461. laShowSeparator(uil,c)->Expand=1; laShowItem(uil,c,This,"operation");
  462. laEndRow(uil,b);
  463. b=laBeginRow(uil,c,0,0);
  464. laShowNodeSocket(uil,c,This,"in_r",0); b=laOnConditionThat(uil,c,laNot(laPropExpression(This,"in_r.source")));{ laShowItem(uil,c,This,"vr");}laEndCondition(uil,b);
  465. laShowSeparator(uil,c)->Expand=1;
  466. laShowNodeSocket(uil,c,This,"out_int",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  467. laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  468. laEndRow(uil,b);
  469. }
  470. void laui_SmallMathNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  471. laColumn* c=laFirstColumn(uil); laMathNode*n=This->EndInstance;
  472. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  473. laUiItem*b,*b2;
  474. LA_BASE_NODE_HEADER(uil,c,This);
  475. b=laBeginRow(uil,c,0,0);
  476. laShowNodeSocket(uil,c,This,"in_l",0);laShowNodeSocket(uil,c,This,"in_r",0);
  477. laShowSeparator(uil,c)->Expand=1;laShowItem(uil,c,This,"operation");
  478. laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  479. laEndRow(uil,b);
  480. }
  481. void IDN_MapperInit(laMapperNode* n, int NoCreate){
  482. if(!NoCreate){
  483. strSafeSet(&n->Base.Name,"Mapper");
  484. n->In=laCreateInSocket("IN",LA_PROP_FLOAT); n->Out=laCreateOutSocket(n,"OUT",LA_PROP_FLOAT);
  485. n->Mapper=laValueMapperInit();
  486. }
  487. n->Out->Data=&n->rOut;
  488. }
  489. void IDN_MapperDestroy(laMapperNode* n){
  490. strSafeDestroy(&n->Base.Name);
  491. laDestroyInSocket(n->In); laDestroyOutSocket(n->Out);
  492. laValueMapperDestroy(n->Mapper);
  493. }
  494. int IDN_MapperVisit(laMapperNode* n, laListHandle* l){
  495. LA_GUARD_THIS_NODE(n);
  496. if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* bn=n->In->Source->Parent; LA_VISIT_NODE(bn); }
  497. n->Base.Eval=LA_DAG_FLAG_PERM;
  498. lstAppendPointer(l, n);
  499. return LA_DAG_FLAG_PERM;
  500. }
  501. int IDN_MapperEval(laMapperNode* n){
  502. real in=0;
  503. if(LA_SRC_AND_PARENT(n->In) && (n->In->Source->DataType&LA_PROP_FLOAT)){ in=*((real*)n->In->Source->Data); }
  504. real result=laValueMapperEvaluate(n->Mapper,in);
  505. n->rOut=result;
  506. return 1;
  507. }
  508. void laui_MapperNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  509. laColumn* c=laFirstColumn(uil); laMapperNode*n=This->EndInstance;
  510. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  511. laUiItem*b,*b2;
  512. LA_BASE_NODE_HEADER(uil,c,This);
  513. b=laBeginRow(uil,c,0,0);
  514. laShowNodeSocket(uil,c,This,"in",0)->Flags|=LA_UI_SOCKET_LABEL_E; laShowItem(uil,c,This,"mapper.in_range")->Expand=1;
  515. laEndRow(uil,b);
  516. laShowItem(uil,c,This,"mapper");
  517. b=laBeginRow(uil,c,0,0);
  518. laShowItem(uil,c,This,"mapper.out_range")->Expand=1;laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  519. laEndRow(uil,b);
  520. }
  521. void IDN_RandomInit(laRandomNode* n, int NoCreate){
  522. if(!NoCreate){
  523. strSafeSet(&n->Base.Name,"Random"); n->Out=laCreateOutSocket(n,"RAND",LA_PROP_FLOAT); n->Min=0; n->Max=1;
  524. }
  525. n->Out->Data=&n->rOut;
  526. }
  527. void IDN_RandomDestroy(laRandomNode* n){
  528. strSafeDestroy(&n->Base.Name); laDestroyOutSocket(n->Out);
  529. }
  530. int IDN_RandomVisit(laRandomNode* n, laListHandle* l){
  531. LA_GUARD_THIS_NODE(n); n->Base.Eval=LA_DAG_FLAG_PERM; lstAppendPointer(l, n);
  532. return LA_DAG_FLAG_PERM;
  533. }
  534. int IDN_RandomEval(laRandomNode* n){
  535. n->rOut=n->Min+(real)rand()/(real)(RAND_MAX/(n->Max-n->Min));
  536. return 1;
  537. }
  538. void laui_RandomNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  539. laColumn* c=laFirstColumn(uil); laRandomNode*n=This->EndInstance;
  540. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  541. laUiItem*b,*b2;
  542. LA_BASE_NODE_HEADER(uil,c,This);
  543. b=laBeginRow(uil,c,0,0);
  544. laShowItem(uil,c,This,"range")->Expand=1;laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  545. laEndRow(uil,b);
  546. }
  547. void IDN_VectorMathInit(laVectorMathNode* n, int NoCreate){
  548. if(!NoCreate){
  549. strSafeSet(&n->Base.Name,"Math");
  550. n->InL=laCreateInSocket("l",0); n->InR=laCreateInSocket("r",0);
  551. n->Out=laCreateOutSocket(n,"OUT",LA_PROP_FLOAT);
  552. }
  553. n->Out->Data=n->rOut;
  554. }
  555. void IDN_VectorMathDestroy(laVectorMathNode* n){
  556. strSafeDestroy(&n->Base.Name); laDestroyInSocket(n->InL); laDestroyInSocket(n->InR); laDestroyOutSocket(n->Out);
  557. }
  558. int IDN_VectorMathVisit(laVectorMathNode* n, laListHandle* l){
  559. LA_GUARD_THIS_NODE(n);
  560. if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
  561. if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn); }
  562. n->Base.Eval=LA_DAG_FLAG_PERM;
  563. lstAppendPointer(l, n);
  564. return LA_DAG_FLAG_PERM;
  565. }
  566. #define LA_GET_SRC_AS_FLOAT_THINGS(var, socket, maxlen)\
  567. {if(socket->Source->DataType&LA_PROP_FLOAT){ real*adr=socket->Source->Data; maxlen=TNS_MIN2(TNS_MAX2(1,socket->Source->ArrLen),maxlen); for(int i=0;i<maxlen;i++){ var[i]=adr[i]; } }\
  568. if(socket->Source->DataType&(LA_PROP_INT|LA_PROP_ENUM)){ int*adr=socket->Source->Data; maxlen=TNS_MIN2(TNS_MAX2(1,socket->Source->ArrLen),maxlen); for(int i=0;i<maxlen;i++){ var[i]=adr[i]; } }\
  569. }
  570. int IDN_VectorMathEval(laVectorMathNode* n){
  571. real vl[4]={0,0,0,1};real vr[4]={0,0,0,1}; int maxlen1=4,maxlen2=4,maxlen;
  572. int hasl=LA_SRC_AND_PARENT(n->InL),hasr=LA_SRC_AND_PARENT(n->InR);
  573. if(hasl){ LA_GET_SRC_AS_FLOAT_THINGS(vl,n->InL,maxlen1) } if(hasr){ LA_GET_SRC_AS_FLOAT_THINGS(vr,n->InR,maxlen2) }
  574. if(maxlen1>1 && maxlen2<maxlen1){ for(int i=maxlen2;i<maxlen1;i++){ vr[i]=vr[maxlen2-1]; } maxlen=maxlen1; }
  575. else{ maxlen=TNS_MIN2(maxlen1,maxlen2); }
  576. switch(n->Operation){
  577. case LA_VECTOR_MATH_OP_ADD: default:n->Out->ArrLen=maxlen; for(int i=0;i<maxlen;i++)n->rOut[i]=vl[i]+vr[i]; break;
  578. case LA_VECTOR_MATH_OP_SUB:n->Out->ArrLen=maxlen; for(int i=0;i<maxlen;i++)n->rOut[i]=vl[i]-vr[i]; break;
  579. case LA_VECTOR_MATH_OP_MUL:n->Out->ArrLen=maxlen; for(int i=0;i<maxlen;i++)n->rOut[i]=vl[i]*vr[i]; break;
  580. case LA_VECTOR_MATH_OP_DIV:n->Out->ArrLen=maxlen; for(int i=0;i<maxlen;i++)n->rOut[i]=vl[i]/vr[i]; break;
  581. case LA_VECTOR_MATH_OP_POW:n->Out->ArrLen=maxlen; for(int i=0;i<maxlen;i++)n->rOut[i]=pow(vl[i],vr[i]); break;
  582. case LA_VECTOR_MATH_OP_LOG:n->Out->ArrLen=maxlen; for(int i=0;i<maxlen;i++)n->rOut[i]=log2(vl[i])/log2(vr[i]); break;
  583. case LA_VECTOR_MATH_OP_CROSS: if(maxlen<3) return 0; n->Out->ArrLen=3; tnsVectorCross3d(n->rOut,vl,vr); break;
  584. case LA_VECTOR_MATH_OP_DOT: if(maxlen<2) return 0; n->Out->ArrLen=maxlen; if(maxlen==2) n->rOut[0]=tnsDot2d(vl,vr,0); else n->rOut[0]=tnsDot3d(vl,vr,0); break;
  585. case LA_VECTOR_MATH_OP_NORMALIZE: if(maxlen<2) return 0; n->Out->ArrLen=maxlen; if(maxlen==2) tnsNormalize2d(n->rOut, vl); else tnsNormalize3d(n->rOut, vl); break;
  586. }
  587. return 1;
  588. }
  589. void laui_VectorMathNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  590. laColumn* c=laFirstColumn(uil); laVectorMathNode*n=This->EndInstance;
  591. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  592. laUiItem*b,*b2;
  593. LA_BASE_NODE_HEADER(uil,c,This);
  594. b=laBeginRow(uil,c,0,0);
  595. laShowNodeSocket(uil,c,This,"in_l",0); laShowNodeSocket(uil,c,This,"in_r",0);
  596. laShowSeparator(uil,c)->Expand=1;
  597. laShowItem(uil,c,This,"operation");
  598. laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  599. laEndRow(uil,b);
  600. }
  601. void IDN_CommentInit(laCommentNode* n, int NoCreate){
  602. if(NoCreate){return;}
  603. strSafeSet(&n->Base.Name,"Math"); strSafeSet(&n->Content,"");
  604. }
  605. void IDN_CommentDestroy(laCommentNode* n){
  606. strSafeDestroy(&n->Base.Name); strSafeDestroy(&n->Content);
  607. }
  608. int IDN_CommentVisit(laCommentNode* n, laListHandle* l){
  609. LA_GUARD_THIS_NODE(n); n->Base.Eval=LA_DAG_FLAG_PERM; lstAppendPointer(l, n);
  610. return LA_DAG_FLAG_PERM;
  611. }
  612. int IDN_CommentEval(laCommentNode* n){ return 1; }
  613. void laui_CommentNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  614. laColumn* c=laFirstColumn(uil); laCommentNode*n=This->EndInstance;
  615. LA_BASE_NODE_HEADER(uil,c,This);
  616. laShowItemFull(uil,c,This,"content",LA_WIDGET_STRING_MULTI,0,0,0)->Flags|=LA_UI_FLAGS_NO_SCROLL_INACTIVE;
  617. }
  618. void IDN_RGB2OKHSLInit(laRGB2OKHSLNode* n, int NoCreate){
  619. if(!NoCreate){
  620. strSafeSet(&n->Base.Name,"RGB to OKHL"); n->In=laCreateInSocket("IN",LA_PROP_FLOAT);
  621. n->OutH=laCreateOutSocket(n,"H",LA_PROP_FLOAT);
  622. n->OutS=laCreateOutSocket(n,"S",LA_PROP_FLOAT);
  623. n->OutL=laCreateOutSocket(n,"L",LA_PROP_FLOAT);
  624. tnsVectorSet3(n->RGB,0.2,0.2,0.2);
  625. }
  626. n->OutH->Data=&n->rOut[0]; n->OutS->Data=&n->rOut[1]; n->OutL->Data=&n->rOut[2];
  627. }
  628. void IDN_RGB2OKHSLDestroy(laRGB2OKHSLNode* n){
  629. strSafeDestroy(&n->Base.Name);
  630. laDestroyInSocket(n->In); laDestroyOutSocket(n->OutH); laDestroyOutSocket(n->OutS); laDestroyOutSocket(n->OutL);
  631. }
  632. int IDN_RGB2OKHSLVisit(laRGB2OKHSLNode* n, laListHandle* l){
  633. LA_GUARD_THIS_NODE(n);
  634. if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* bn=n->In->Source->Parent; LA_VISIT_NODE(bn); }
  635. n->Base.Eval=LA_DAG_FLAG_PERM;
  636. lstAppendPointer(l, n);
  637. return LA_DAG_FLAG_PERM;
  638. }
  639. int IDN_RGB2OKHSLEval(laRGB2OKHSLNode* n){
  640. real* in=n->RGB;
  641. if(LA_SRC_AND_PARENT(n->In) && (n->In->Source->DataType==(LA_PROP_FLOAT|LA_PROP_ARRAY) && n->In->Source->ArrLen>=3)){ in=n->In->Source->Data; }
  642. tnsRGB2HCYLinear(in, n->rOut);
  643. return 1;
  644. }
  645. void laui_RGB2OKHSLNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  646. laColumn* c=laFirstColumn(uil); laRGB2OKHSLNode*n=This->EndInstance;
  647. laUiItem*b,*b2;
  648. LA_BASE_NODE_HEADER(uil,c,This);
  649. b=laBeginRow(uil,c,0,0);
  650. laShowNodeSocket(uil,c,This,"in",0); laShowNodeSocket(uil,c,This,"color",0); laShowSeparator(uil,c)->Expand=1;
  651. laShowItem(uil,c,This,"out_h")->Flags|=LA_UI_SOCKET_LABEL_W;
  652. laShowItem(uil,c,This,"out_s")->Flags|=LA_UI_SOCKET_LABEL_W;
  653. laShowItem(uil,c,This,"out_l")->Flags|=LA_UI_SOCKET_LABEL_W;
  654. laEndRow(uil,b);
  655. }
  656. void IDN_OKHSL2RGBInit(laOKHSL2RGBNode* n, int NoCreate){
  657. if(!NoCreate){
  658. strSafeSet(&n->Base.Name,"OKHL to RGB"); n->Out=laCreateOutSocket(n,"RGB",LA_PROP_FLOAT|LA_PROP_ARRAY);
  659. n->InH=laCreateInSocket("H",LA_PROP_FLOAT);
  660. n->InS=laCreateInSocket("S",LA_PROP_FLOAT);
  661. n->InL=laCreateInSocket("L",LA_PROP_FLOAT);
  662. }
  663. n->Out->ArrLen=3; n->Out->Data=n->rOut;
  664. }
  665. void IDN_OKHSL2RGBDestroy(laOKHSL2RGBNode* n){
  666. strSafeDestroy(&n->Base.Name);
  667. laDestroyInSocket(n->InH); laDestroyInSocket(n->InS); laDestroyInSocket(n->InL); laDestroyOutSocket(n->Out);
  668. }
  669. int IDN_OKHSL2RGBVisit(laOKHSL2RGBNode* n, laListHandle* l){
  670. LA_GUARD_THIS_NODE(n);
  671. if(LA_SRC_AND_PARENT(n->InH)){ laBaseNode* bn=n->InH->Source->Parent; LA_VISIT_NODE(bn); }
  672. if(LA_SRC_AND_PARENT(n->InS)){ laBaseNode* bn=n->InS->Source->Parent; LA_VISIT_NODE(bn); }
  673. if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
  674. n->Base.Eval=LA_DAG_FLAG_PERM;
  675. lstAppendPointer(l, n);
  676. return LA_DAG_FLAG_PERM;
  677. }
  678. int IDN_OKHSL2RGBEval(laOKHSL2RGBNode* n){
  679. real in[3]={0,0,0};
  680. if(LA_SRC_AND_PARENT(n->InH) && (n->InH->Source->DataType&LA_PROP_FLOAT)){ in[0]=*((real*)n->InH->Source->Data); }
  681. if(LA_SRC_AND_PARENT(n->InS) && (n->InS->Source->DataType&LA_PROP_FLOAT)){ in[1]=*((real*)n->InS->Source->Data); }
  682. if(LA_SRC_AND_PARENT(n->InL) && (n->InL->Source->DataType&LA_PROP_FLOAT)){ in[2]=*((real*)n->InL->Source->Data); }
  683. tnsHCY2RGBLinear(in, n->rOut);
  684. return 1;
  685. }
  686. void laui_OKHSL2RGBNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  687. laColumn* c=laFirstColumn(uil); laOKHSL2RGBNode*n=This->EndInstance;
  688. laUiItem*b,*b2;
  689. LA_BASE_NODE_HEADER(uil,c,This);
  690. b=laBeginRow(uil,c,0,0);
  691. laShowItem(uil,c,This,"in_h")->Flags|=LA_UI_SOCKET_LABEL_E;
  692. laShowItem(uil,c,This,"in_s")->Flags|=LA_UI_SOCKET_LABEL_E;
  693. laShowItem(uil,c,This,"in_l")->Flags|=LA_UI_SOCKET_LABEL_E;
  694. laShowSeparator(uil,c)->Expand=1; laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  695. laEndRow(uil,b);
  696. }
  697. int OPINV_AddInputMapperPage(laOperator* a, laEvent *e){
  698. laRackPage* dp=memAcquireHyper(sizeof(laRackPage));
  699. strSafeSet(&dp->Name,"New Page");
  700. lstAppendItem(&MAIN.InputMapping->Pages, dp); MAIN.InputMapping->CurrentPage=dp; dp->RackType=LA_RACK_TYPE_INPUT;
  701. laNotifyUsers("la.input_mapping"); laRecordAndPush(0,"la.input_mapping","Add Page", 0);
  702. return LA_FINISHED;
  703. }
  704. int OPINV_AddNodesRack(laOperator* a, laEvent *e){
  705. laRackPage* dp=a->This?a->This->EndInstance:0; if(!dp) return LA_FINISHED;
  706. laNodeRack* ir=memAcquire(sizeof(laNodeRack));
  707. strSafeSet(&ir->Name,"New Rack");
  708. lstAppendItem(&dp->Racks, ir); ir->ParentPage=dp;
  709. ir->RackType=dp->RackType;
  710. laNotifyInstanceUsers(dp); laRecordInstanceDifferences(dp,"la_node_rack"); laPushDifferences("Add Rack", 0);
  711. return LA_FINISHED;
  712. }
  713. int OPINV_RebuildInputMapping(laOperator* a, laEvent *e){
  714. laMappingRequestRebuild();
  715. return LA_FINISHED;
  716. }
  717. laBaseNode* la_CreateNode(laNodeRack* ir, laBaseNodeType* NodeType){
  718. laBaseNode* bn=memAcquire(NodeType->NodeSize);
  719. bn->Type=NodeType; NodeType->Init(bn, 0); bn->InitDone=1; lstAppendItem(&ir->Nodes, bn); bn->InRack=ir;
  720. laNotifyInstanceUsers(ir); laRecordInstanceDifferences(ir,"la_node_rack"); laPushDifferences("Add Node", 0);
  721. return bn;
  722. }
  723. void la_DestroyInputMapperNode(laBaseNode* bn){
  724. lstRemoveItem(bn->InRack, bn); bn->Type->Destroy(bn);
  725. laNotifyUsers("la.input_racks"); laRecordAndPush(0,"la.input_mapping","Delete node", 0);
  726. memLeave(bn);
  727. }
  728. int OPINV_AddNode(laOperator* a, laEvent *e){
  729. laNodeRack* ir=a->This?a->This->EndInstance:0; if(!ir) return LA_CANCELED;
  730. laBaseNodeType* bnt=0;
  731. if(!MAIN.CurrentNodeCategory) MAIN.CurrentNodeCategory=MAIN.NodeCategories.pFirst;
  732. char* target=strGetArgumentString(a->ExtraInstructionsP,"target");
  733. if(!target || strSame(target,"INPUT")){ MAIN.FilterNodeCategory=LA_RACK_TYPE_INPUT;
  734. if(!(MAIN.CurrentNodeCategory->For&LA_RACK_TYPE_INPUT)) MAIN.CurrentNodeCategory=LA_NODE_CATEGORY_INPUT; }
  735. else{ MAIN.FilterNodeCategory=LA_RACK_TYPE_DRIVER;
  736. if(!(MAIN.CurrentNodeCategory->For&LA_RACK_TYPE_DRIVER)) MAIN.CurrentNodeCategory=LA_NODE_CATEGORY_DRIVER; }
  737. char* type=strGetArgumentString(a->ExtraInstructionsP,"type");
  738. if(!type){ laEnableOperatorPanel(a,a->This,e->x-LA_RH*4,e->y-LA_RH,200,200,0,0,LA_RH*15,0,0,0,0,0,e); return LA_RUNNING; }
  739. else{
  740. for(int i=0;i<MAIN.NodeTypeNext;i++){
  741. if(strSame(MAIN.NodeTypes[i]->TypeName,type)){ la_CreateNode(ir, MAIN.NodeTypes[i]); }
  742. }
  743. }
  744. return LA_FINISHED;
  745. }
  746. int OPMOD_AddNode(laOperator* a, laEvent *e){
  747. laNodeRack* r=a->This->EndInstance;
  748. if(a->ConfirmData){
  749. if(a->ConfirmData->StrData){
  750. for(int i=0;i<MAIN.NodeTypeNext;i++){
  751. if(strSame(MAIN.NodeTypes[i]->TypeName,a->ConfirmData->StrData)){ la_CreateNode(r, MAIN.NodeTypes[i]); break; }
  752. }
  753. }
  754. return LA_FINISHED;
  755. }
  756. return LA_RUNNING;
  757. }
  758. void laui_AddNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  759. laColumn* c=laFirstColumn(uil),*cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,4); cr=laRightColumn(c,0);
  760. laShowItemFull(uil,cl,0,"la.node_categories",LA_WIDGET_COLLECTION,"feedback=NONE;",0,0);
  761. laUiItem* g=laMakeEmptyGroup(uil,cr,"Nodes",0); laUiList* gu=g->Page; laColumn* gc=laFirstColumn(gu); g->Flags|=LA_UI_FLAGS_NO_DECAL|LA_UI_FLAGS_NO_GAP;
  762. laShowItemFull(gu,gc,0,"la.node_categories",LA_WIDGET_COLLECTION_SINGLE,0,laui_NodeCategory,0)->Flags|=LA_UI_FLAGS_NO_DECAL;
  763. }
  764. int OPINV_MoveNodeToRack(laOperator* a, laEvent *e){
  765. laBaseNode* n=a->This?a->This->EndInstance:0; if(!n||!n->InRack) return LA_CANCELED;
  766. laBaseNodeType* bnt=0; laNodeRack* target;
  767. char* direction=strGetArgumentString(a->ExtraInstructionsP,"direction");
  768. if(strSame(direction,"left")) target=n->InRack->Item.pPrev; else target=n->InRack->Item.pNext;
  769. if(!target) return LA_CANCELED;
  770. lstRemoveItem(&n->InRack->Nodes, n); lstAppendItem(&target->Nodes,n); n->InRack=target;
  771. laNotifyInstanceUsers(n->InRack->ParentPage); laRecordInstanceDifferences(n->InRack->ParentPage,"la_node_page"); laPushDifferences("Move Node", 0);
  772. return LA_FINISHED;
  773. }
  774. int OPINV_DeleteNode(laOperator* a, laEvent *e){
  775. laBaseNode* n=a->This?a->This->EndInstance:0; if(!n||!n->InRack) return LA_CANCELED;
  776. laBaseNodeType* bnt=0; laNodeRack* target;
  777. laNodeRack* parent=n->InRack;
  778. lstRemoveItem(&n->InRack->Nodes, n); n->Type->Destroy(n); memLeave(n);
  779. laMappingRequestRebuild(); laDriverRequestRebuild();
  780. laNotifyInstanceUsers(parent); laRecordInstanceDifferences(parent,"la_node_rack"); laPushDifferences("Delete Node", 0);
  781. return LA_FINISHED;
  782. }
  783. int OPINV_MoveRack(laOperator* a, laEvent *e){
  784. laNodeRack* r=a->This?a->This->EndInstance:0; if(!r) return LA_CANCELED;
  785. char* direction=strGetArgumentString(a->ExtraInstructionsP,"direction");
  786. if(strSame(direction,"left")) lstMoveUp(&r->ParentPage->Racks,r); else lstMoveDown(&r->ParentPage->Racks,r);
  787. laNotifyInstanceUsers(r->ParentPage); laRecordInstanceDifferences(r->ParentPage,"la_rack_page"); laPushDifferences("Move Rack", 0);
  788. return LA_FINISHED;
  789. }
  790. int OPINV_InsertRack(laOperator* a, laEvent *e){
  791. laNodeRack* rr=a->This?a->This->EndInstance:0; if(!rr) return LA_CANCELED;
  792. laNodeRack* r=memAcquire(sizeof(laNodeRack));
  793. strSafeSet(&r->Name,"New Rack");
  794. lstInsertItemAfter(&rr->ParentPage->Racks,r,rr); r->ParentPage=rr->ParentPage; r->RackType=rr->RackType;
  795. laNotifyInstanceUsers(r->ParentPage); laRecordInstanceDifferences(r->ParentPage,"la_rack_page"); laPushDifferences("Insert Rack", 0);
  796. return LA_FINISHED;
  797. }
  798. int OPINV_DeleteRack(laOperator* a, laEvent *e){
  799. laNodeRack* rr=a->This?a->This->EndInstance:0; if(!rr) return LA_CANCELED;
  800. if(strSame(strGetArgumentString(a->ExtraInstructionsP,"confirm"),"true")){
  801. laBaseNode* n; while(n=lstPopItem(&rr->Nodes)){ n->Type->Destroy(n); memLeave(n); }
  802. laRackPage* page=rr->ParentPage;
  803. strSafeDestroy(&rr->Name); lstRemoveItem(&rr->ParentPage->Racks, rr); memLeave(rr);
  804. laNotifyInstanceUsers(page); laRecordInstanceDifferences(page,"la_rack_page"); laPushDifferences("Delete Rack", 0);
  805. return LA_FINISHED;
  806. }
  807. laEnableOperatorPanel(a,a->This,e->x,e->y,200,200,0,0,0,0,0,0,0,0,e);
  808. return LA_RUNNING;
  809. }
  810. void laui_DeleteRack(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  811. laColumn* c=laFirstColumn(uil);
  812. laShowItemFull(uil,c,This,"delete",0,"confirm=true;",0,0);
  813. }
  814. laPropContainer* laget_BaseNodeType(laBaseNode* bn){
  815. for(int i=0;i<MAIN.NodeTypeNext;i++){ if(bn->Type==MAIN.NodeTypes[i]) return MAIN.NodeTypes[i]->pc; }
  816. return LA_PC_IDN_GENERIC;
  817. }
  818. int laget_BaseNodeGap(laNodeRack* rack_unused, laBaseNode* n){
  819. return n->Gap;
  820. }
  821. void laset_BaseNodeGap(laBaseNode* n, int gap){
  822. laBaseNode* nn;
  823. if(gap==-1){
  824. int done=0; nn=n; while(nn){ if(nn->Gap>0){ nn->Gap--; done=1; break; } nn=nn->Item.pPrev; }
  825. if(done){ nn=n->Item.pNext; while(nn){ if(nn->Gap>0){ nn->Gap++; break; } nn=nn->Item.pNext; } }
  826. }elif(gap==1){
  827. n->Gap+=gap; nn=n->Item.pNext; while(nn){ if(nn->Gap>0){ nn->Gap--; break; } nn=nn->Item.pNext; }
  828. }elif(gap==-2){
  829. if(n->Gap){ n->Gap--; if(nn=n->Item.pNext){ nn->Gap++; } }
  830. elif(nn=n->Item.pPrev){ n->Gap=nn->Gap; nn->Gap=0; lstRemoveItem(&n->InRack->Nodes,n); lstInsertItemBefore(&n->InRack->Nodes,n,nn); }
  831. }elif(gap==2){
  832. if(nn=n->Item.pNext){ if(!nn->Gap){ nn->Gap=n->Gap; n->Gap=0; lstRemoveItem(&n->InRack->Nodes,n); lstInsertItemAfter(&n->InRack->Nodes,n,nn); }else{ nn->Gap--; n->Gap++; } }
  833. else n->Gap++;
  834. }
  835. }
  836. void laset_InputNodeUserID(laInputControllerNode* n, int i){
  837. laNotifyUsers("la.input_racks");
  838. }
  839. void laset_InputControllerNodeSocketWhich(laInputControllerNodeSocket* s, char* str){
  840. strSafeSet(&s->Which, str);
  841. laNotifyUsers("la.input_racks"); laMappingRequestRebuild();
  842. }
  843. int laget_SocketEnumArrayLength(laInputControllerNodeSocket* s){
  844. return s->Out->ArrLen?s->Out->ArrLen:1;
  845. }
  846. int laget_VisualizerArrayLength(laInputVisualizerNode* s){
  847. return s->In->ArrLen?s->In->ArrLen:1;
  848. }
  849. laBoxedTheme* laget_NodeGetTheme(laNodeRack* rack_unused, laBaseNode* n){
  850. return 0;
  851. }
  852. void laRegisterNode(laBaseNodeType* type, laPropContainer* pc,
  853. laBaseNodeInitF init, laBaseNodeDestroyF destroy, laBaseNodeVisitF visit, laBaseNodeEvalF eval,
  854. int nodesize, char* udf_string, char* type_string, char* UiText, int icon){
  855. arrEnsureLength(&MAIN.NodeTypes, MAIN.NodeTypeNext, &MAIN.NodeTypeMax, sizeof(laBaseNode*));
  856. type->Init = init; type->Destroy = destroy; type->Visit=visit; type->Eval=eval; type->NodeSize=nodesize; type->pc=pc;
  857. type->TypeName=type_string;type->Name=UiText;type->Icon=icon;
  858. MAIN.NodeTypes[MAIN.NodeTypeNext]=type; MAIN.NodeTypeNext++;
  859. la_UDFAppendSharedTypePointer(udf_string, type);
  860. }
  861. void la_AddValuesNodeEnum(laProp* p){
  862. laAddEnumItemAs(p,"FLOAT","Float","Float value",LA_VALUES_NODE_FLOAT,0);
  863. laAddEnumItemAs(p,"INT","Int","Int value",LA_VALUES_NODE_INT,0);
  864. laAddEnumItemAs(p,"ENUM","Switch","Swich value",LA_VALUES_NODE_ENUM,0);
  865. }
  866. void la_AddValuesNodeEnumValue(laProp* p){
  867. laAddEnumItemAs(p,"IDLE","Idle","Idle",0,0);
  868. laAddEnumItemAs(p,"ACTIVE","Active","Active",1,0);
  869. }
  870. void la_RegisterInputMapperOperators(){
  871. laPropContainer *pc; laProp *p;
  872. laOperatorType *at;
  873. laEnumProp *ep;
  874. laCreateOperatorType("LA_add_input_mapping_page", "Add Page", "Add a page for inpur mapping", 0,0,0,OPINV_AddInputMapperPage,0,'+',0);
  875. laCreateOperatorType("LA_add_rack", "Add Rack", "Add a rack for nodes", 0,0,0,OPINV_AddNodesRack,0,'+',0);
  876. at=laCreateOperatorType("OPINV_AddNode", "Add Node", "Add a node to the rack",0,0,0,OPINV_AddNode,OPMOD_AddNode,'+',0);
  877. at->UiDefine=laui_AddNode;
  878. laCreateOperatorType("LA_input_mapping_rebuild", "Rebuild Input Mapping", "Rebuild input mapping for evaluation",0,0,0,OPINV_RebuildInputMapping,0,L'⭮',0);
  879. laCreateOperatorType("LA_move_node_to_rack", "Move Node", "Move node to another rack",0,0,0,OPINV_MoveNodeToRack,0,0,0);
  880. laCreateOperatorType("LA_delete_node", "Delete Node", "Delete this node",0,0,0,OPINV_DeleteNode,0,0,0);
  881. laCreateOperatorType("LA_move_rack", "Move Rack", "Move this rack",0,0,0,OPINV_MoveRack,0,0,0);
  882. laCreateOperatorType("LA_insert_rack", "Insert Rack", "Insert a new rack",0,0,0,OPINV_InsertRack,0,0,0);
  883. at=laCreateOperatorType("LA_delete_rack", "Delete Rack", "Delete a rack",0,0,0,OPINV_DeleteRack,OPMOD_FinishOnData,L'❌',0);
  884. at->UiDefine=laui_DeleteRack;
  885. pc=laAddPropertyContainer("la_node_rack", "Input Rack", "Input rack for putting input mapping nodes",0,0,sizeof(laNodeRack),0,0,1);
  886. laAddStringProperty(pc,"name","Name","Name of this rack",0,0,0,0,1,offsetof(laNodeRack,Name),0,0,0,0,LA_AS_IDENTIFIER);
  887. p=laAddSubGroup(pc,"nodes","Nodes","Nodes under this rack","la_base_node",laget_BaseNodeType,0,0,-1,0,0,0,0,0,0,offsetof(laNodeRack,Nodes),0);
  888. laSubGroupExtraFunctions(p,0,laget_NodeGetTheme,laget_BaseNodeGap,0);
  889. laAddSubGroup(pc,"parent_page","Parent Page","Parent page of this rack","la_rack_page",0,0,0,offsetof(laNodeRack,ParentPage),0,0,0,0,0,0,0,LA_UDF_REFER);
  890. laAddIntProperty(pc,"type", "Type", "Type of the rack", 0,0,0,0,0,0,0,0,offsetof(laNodeRack,RackType),0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY);
  891. laAddOperatorProperty(pc,"add_node","Add Node","Add a node into this rack","OPINV_AddNode",'+',0);
  892. laAddOperatorProperty(pc,"insert_rack","Insert Rack","Insert a rack","LA_insert_rack",'+',0);
  893. laAddOperatorProperty(pc,"move","Move Rack","Move this rack","LA_move_rack",0,0);
  894. laAddOperatorProperty(pc,"delete","Delete Rack","Delete this rack","LA_delete_rack",0,0);
  895. pc=laAddPropertyContainer("la_base_node", "Input Node", "Input logic node",0,0,sizeof(laBaseNode),0,0,1);
  896. LA_PC_IDN_GENERIC=pc;
  897. laAddStringProperty(pc,"name","Name","Name of this input node",0,0,0,0,1,offsetof(laBaseNode,Name),0,0,0,0,LA_AS_IDENTIFIER);
  898. laAddIntProperty(pc,"__gap", "Gap", "Gap of the node", 0,0,0,0,0,0,0,0,offsetof(laBaseNode,Gap),0,laset_BaseNodeGap,0,0,0,0,0,0,0,0,0);
  899. laAddSubGroup(pc,"internal_type","Internal Type","Internal node type","any_pointer",0,0,0,offsetof(laBaseNode,Type),0,0,0,0,0,0,0,LA_READ_ONLY|LA_UDF_REFER);
  900. laAddOperatorProperty(pc,"move","Move","Move node across racks","LA_move_node_to_rack",0,0);
  901. laAddOperatorProperty(pc,"delete","Delete","Delete node","LA_delete_node",0,0);
  902. laAddSubGroup(pc,"in_rack","In Rack","The rack this node is in","la_node_rack",0,0,0,offsetof(laBaseNode,InRack),0,0,0,0,0,0,0,LA_UDF_REFER);
  903. pc=laAddPropertyContainer("la_input_controller_node", "Controller output", "Output controller values",0,laui_ControllerNode,sizeof(laInputControllerNode),0,0,1);
  904. LA_PC_IDN_CONTROLLER=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  905. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  906. laAddIntProperty(pc,"user_id", "User ID", "Which controller should the data come from", 0,0,0,0,0,0,0,0,offsetof(laInputControllerNode,UserID),0,0,0,0,0,0,0,0,0,0,0);
  907. laAddSubGroup(pc,"out0","Out 0","Output 0","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[0]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  908. laAddSubGroup(pc,"out1","Out 1","Output 1","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[1]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  909. laAddSubGroup(pc,"out2","Out 2","Output 2","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[2]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  910. laAddSubGroup(pc,"out3","Out 3","Output 3","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[3]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  911. laAddSubGroup(pc,"out4","Out 4","Output 4","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[4]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  912. laAddSubGroup(pc,"out5","Out 5","Output 5","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[5]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  913. laAddSubGroup(pc,"out6","Out 6","Output 6","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[6]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  914. laAddSubGroup(pc,"out7","Out 7","Output 7","la_input_controller_node_socket",0,0,0,offsetof(laInputControllerNode, Sockets[7]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  915. pc=laAddPropertyContainer("la_input_controller_node_socket", "Controller Socket", "One value from a controller output",0,0,sizeof(laInputControllerNodeSocket),0,0,1|LA_PROP_OTHER_ALLOC);
  916. laAddStringProperty(pc,"which","Which","Select which output from the controller",0,0,0,0,1,offsetof(laInputControllerNodeSocket,Which),0,0,laset_InputControllerNodeSocketWhich,0,LA_AS_IDENTIFIER);
  917. laAddFloatProperty(pc,"axis", "🡘", "Axis value", LA_WIDGET_VALUE_METER,0,0,1,-1,0,0,0,offsetof(laInputControllerNodeSocket,RealVal),0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY|LA_UDF_IGNORE);
  918. laAddFloatProperty(pc,"axis2d", "2D Axis", "2D Axis value", LA_WIDGET_VALUE_METER,0,0,1,-1,0,0,0,offsetof(laInputControllerNodeSocket,RealVal),0,0,2,0,0,0,0,0,0,0,LA_READ_ONLY|LA_UDF_IGNORE);
  919. p=laAddEnumProperty(pc,"switch", "SW", "Switch value", LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(laInputControllerNodeSocket,IntVal),0,0,0,laget_SocketEnumArrayLength,0,0,0,0,0,LA_READ_ONLY|LA_UDF_IGNORE);
  920. laAddEnumItemAs(p,"IDLE", "Idle", "Button is not pressed", 0, 0);
  921. laAddEnumItemAs(p,"ACTIVE", "Active", "Button is pressed", 1, 0);
  922. laAddSubGroup(pc, "out", "Out","Output value","la_out_socket",0,0,0,offsetof(laInputControllerNodeSocket,Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  923. pc=laAddPropertyContainer("la_input_visualizer_node", "Visualizer", "Visualizer node",0,laui_InputVisualizeNode,sizeof(laInputVisualizerNode),0,0,1);
  924. LA_PC_IDN_VISUALIZER=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  925. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  926. laAddSubGroup(pc, "in", "In","Input value","la_in_socket",0,0,0,offsetof(laInputVisualizerNode,In),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  927. laAddFloatProperty(pc,"axis", "🡘", "Axis value", LA_WIDGET_VALUE_METER,0,0,1,-1,0,0,0,offsetof(laInputVisualizerNode,RealVal),0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY|LA_UDF_IGNORE);
  928. laAddFloatProperty(pc,"axis2d", "2D Axis", "2D Axis value", LA_WIDGET_VALUE_METER_2D,0,0,1,-1,0,0,0,offsetof(laInputVisualizerNode,RealVal),0,0,2,0,0,0,0,0,0,0,LA_READ_ONLY|LA_UDF_IGNORE);
  929. p=laAddEnumProperty(pc,"switch", "SW", "Switch value", LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(laInputVisualizerNode,IntVal),0,0,0,laget_VisualizerArrayLength,0,0,0,0,0,LA_READ_ONLY|LA_UDF_IGNORE);
  930. laAddEnumItemAs(p,"IDLE", "Idle", "Button is not pressed", 0, 0);
  931. laAddEnumItemAs(p,"ACTIVE", "Active", "Button is pressed", 1, 0);
  932. pc=laAddPropertyContainer("la_split_node", "Split", "Split node",0,laui_SplitNode,sizeof(laSplitNode),0,0,1);
  933. LA_PC_IDN_SPLIT=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  934. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  935. laAddSubGroup(pc,"in", "In","Input value","la_in_socket",0,0,0,offsetof(laSplitNode,In),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  936. laAddSubGroup(pc,"out0","Out 0","Output 0","la_split_node_out_socket",0,0,0,offsetof(laSplitNode, Out[0]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  937. laAddSubGroup(pc,"out1","Out 1","Output 1","la_split_node_out_socket",0,0,0,offsetof(laSplitNode, Out[1]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  938. laAddSubGroup(pc,"out2","Out 2","Output 2","la_split_node_out_socket",0,0,0,offsetof(laSplitNode, Out[2]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  939. laAddSubGroup(pc,"out3","Out 3","Output 3","la_split_node_out_socket",0,0,0,offsetof(laSplitNode, Out[3]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  940. laAddSubGroup(pc,"out4","Out 4","Output 4","la_split_node_out_socket",0,0,0,offsetof(laSplitNode, Out[4]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  941. laAddSubGroup(pc,"out5","Out 5","Output 5","la_split_node_out_socket",0,0,0,offsetof(laSplitNode, Out[5]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  942. laAddSubGroup(pc,"out6","Out 6","Output 6","la_split_node_out_socket",0,0,0,offsetof(laSplitNode, Out[6]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  943. laAddSubGroup(pc,"out7","Out 7","Output 7","la_split_node_out_socket",0,0,0,offsetof(laSplitNode, Out[7]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  944. laAddIntProperty(pc, "array_length", "Array Length", "Array length of data", 0, 0, 0, 0, 0, 0, 0, 0, offsetof(laSplitNode, ArrLen), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,LA_READ_ONLY);
  945. pc=laAddPropertyContainer("la_split_node_out_socket", "Split Out", "One value from an array input",0,0,sizeof(laSplitNodeOutSocket),0,0,1|LA_PROP_OTHER_ALLOC);
  946. laAddSubGroup(pc, "out", "Out","Output value","la_out_socket",0,0,0,offsetof(laSplitNodeOutSocket,Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  947. pc=laAddPropertyContainer("la_switch_node", "Switch", "Switch node",0,laui_SwitchNode,sizeof(laSwitchNode),0,0,1);
  948. LA_PC_IDN_SWITCH=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  949. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  950. laAddSubGroup(pc,"out", "Out","Output value","la_out_socket",0,0,0,offsetof(laSwitchNode, Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  951. laAddSubGroup(pc,"in0","In 0","Input 0","la_switch_node_in_socket",0,0,0,offsetof(laSwitchNode, In[0]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  952. laAddSubGroup(pc,"in1","In 1","Input 1","la_switch_node_in_socket",0,0,0,offsetof(laSwitchNode, In[1]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  953. laAddSubGroup(pc,"in2","In 2","Input 2","la_switch_node_in_socket",0,0,0,offsetof(laSwitchNode, In[2]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  954. laAddSubGroup(pc,"in3","In 3","Input 3","la_switch_node_in_socket",0,0,0,offsetof(laSwitchNode, In[3]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  955. laAddSubGroup(pc,"in4","In 4","Input 4","la_switch_node_in_socket",0,0,0,offsetof(laSwitchNode, In[4]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  956. laAddSubGroup(pc,"in5","In 5","Input 5","la_switch_node_in_socket",0,0,0,offsetof(laSwitchNode, In[5]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  957. laAddSubGroup(pc,"in6","In 6","Input 6","la_switch_node_in_socket",0,0,0,offsetof(laSwitchNode, In[6]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  958. laAddSubGroup(pc,"in7","In 7","Input 7","la_switch_node_in_socket",0,0,0,offsetof(laSwitchNode, In[7]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  959. laAddIntProperty(pc, "switch", "Switch", "Switch which input to use", 0, 0, 0, 0, 0, 0, 0, 0, offsetof(laSwitchNode, Switch), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  960. laAddSubGroup(pc,"switch_in", "Switch In","Switch control","la_in_socket",0,0,0,offsetof(laSwitchNode,SwitchIn),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  961. pc=laAddPropertyContainer("la_switch_node_in_socket", "Switch In", "Input of many values",0,0,sizeof(laSwitchNodeInSocket),0,0,1|LA_PROP_OTHER_ALLOC);
  962. laAddSubGroup(pc, "in", "In","Input value","la_in_socket",0,0,0,offsetof(laSwitchNodeInSocket,In),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  963. pc=laAddPropertyContainer("la_combine_node", "Combine", "Combine node",0,laui_CombineNode,sizeof(laCombineNode),0,0,1);
  964. LA_PC_IDN_COMBINE=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  965. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  966. laAddSubGroup(pc,"out", "Out","Output value","la_out_socket",0,0,0,offsetof(laCombineNode, Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  967. laAddSubGroup(pc,"out_int", "Out Int","Output value in int format","la_out_socket",0,0,0,offsetof(laCombineNode, OutInt),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  968. laAddSubGroup(pc,"out_enum", "Out Enum","Output value in Enum format","la_out_socket",0,0,0,offsetof(laCombineNode, OutEnum),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  969. laAddSubGroup(pc,"in0","In 0","Input 0","la_switch_node_in_socket",0,0,0,offsetof(laCombineNode, In[0]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  970. laAddSubGroup(pc,"in1","In 1","Input 1","la_switch_node_in_socket",0,0,0,offsetof(laCombineNode, In[1]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  971. laAddSubGroup(pc,"in2","In 2","Input 2","la_switch_node_in_socket",0,0,0,offsetof(laCombineNode, In[2]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  972. laAddSubGroup(pc,"in3","In 3","Input 3","la_switch_node_in_socket",0,0,0,offsetof(laCombineNode, In[3]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  973. laAddSubGroup(pc,"in4","In 4","Input 4","la_switch_node_in_socket",0,0,0,offsetof(laCombineNode, In[4]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  974. laAddSubGroup(pc,"in5","In 5","Input 5","la_switch_node_in_socket",0,0,0,offsetof(laCombineNode, In[5]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  975. laAddSubGroup(pc,"in6","In 6","Input 6","la_switch_node_in_socket",0,0,0,offsetof(laCombineNode, In[6]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  976. laAddSubGroup(pc,"in7","In 7","Input 7","la_switch_node_in_socket",0,0,0,offsetof(laCombineNode, In[7]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  977. pc=laAddPropertyContainer("la_values_node", "Values", "Values node",0,laui_ValuesNode,sizeof(laValuesNode),0,0,1);
  978. LA_PC_IDN_VALUES=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  979. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  980. laAddSubGroup(pc,"out0","Out 0","Output 0","la_split_node_out_socket",0,0,0,offsetof(laValuesNode, Out[0]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  981. laAddSubGroup(pc,"out1","Out 1","Output 1","la_split_node_out_socket",0,0,0,offsetof(laValuesNode, Out[1]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  982. laAddSubGroup(pc,"out2","Out 2","Output 2","la_split_node_out_socket",0,0,0,offsetof(laValuesNode, Out[2]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  983. laAddSubGroup(pc,"out3","Out 3","Output 3","la_split_node_out_socket",0,0,0,offsetof(laValuesNode, Out[3]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  984. laAddSubGroup(pc,"out4","Out 4","Output 4","la_split_node_out_socket",0,0,0,offsetof(laValuesNode, Out[4]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  985. laAddSubGroup(pc,"out5","Out 5","Output 5","la_split_node_out_socket",0,0,0,offsetof(laValuesNode, Out[5]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  986. laAddSubGroup(pc,"out6","Out 6","Output 6","la_split_node_out_socket",0,0,0,offsetof(laValuesNode, Out[6]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  987. laAddSubGroup(pc,"out7","Out 7","Output 7","la_split_node_out_socket",0,0,0,offsetof(laValuesNode, Out[7]),0,0,0,0,0,0,0,LA_UDF_LOCAL);
  988. p=laAddEnumProperty(pc,"mode0","Mode 0","Mode 0",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, Modes[0]),0,0,0,0,0,0,0,0,0,0); la_AddValuesNodeEnum(p);
  989. p=laAddEnumProperty(pc,"mode1","Mode 1","Mode 1",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, Modes[1]),0,0,0,0,0,0,0,0,0,0); la_AddValuesNodeEnum(p);
  990. p=laAddEnumProperty(pc,"mode2","Mode 2","Mode 2",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, Modes[2]),0,0,0,0,0,0,0,0,0,0); la_AddValuesNodeEnum(p);
  991. p=laAddEnumProperty(pc,"mode3","Mode 3","Mode 3",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, Modes[3]),0,0,0,0,0,0,0,0,0,0); la_AddValuesNodeEnum(p);
  992. p=laAddEnumProperty(pc,"mode4","Mode 4","Mode 4",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, Modes[4]),0,0,0,0,0,0,0,0,0,0); la_AddValuesNodeEnum(p);
  993. p=laAddEnumProperty(pc,"mode5","Mode 5","Mode 5",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, Modes[5]),0,0,0,0,0,0,0,0,0,0); la_AddValuesNodeEnum(p);
  994. p=laAddEnumProperty(pc,"mode6","Mode 6","Mode 6",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, Modes[6]),0,0,0,0,0,0,0,0,0,0); la_AddValuesNodeEnum(p);
  995. p=laAddEnumProperty(pc,"mode7","Mode 7","Mode 7",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, Modes[7]),0,0,0,0,0,0,0,0,0,0); la_AddValuesNodeEnum(p);
  996. laAddIntProperty(pc, "valuei0", "Value", "Int value 0", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, ValuesI[0]),0,0,0,0,0,0,0,0,0,0,0);
  997. laAddIntProperty(pc, "valuei1", "Value", "Int value 1", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, ValuesI[1]),0,0,0,0,0,0,0,0,0,0,0);
  998. laAddIntProperty(pc, "valuei2", "Value", "Int value 2", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, ValuesI[2]),0,0,0,0,0,0,0,0,0,0,0);
  999. laAddIntProperty(pc, "valuei3", "Value", "Int value 3", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, ValuesI[3]),0,0,0,0,0,0,0,0,0,0,0);
  1000. laAddIntProperty(pc, "valuei4", "Value", "Int value 4", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, ValuesI[4]),0,0,0,0,0,0,0,0,0,0,0);
  1001. laAddIntProperty(pc, "valuei5", "Value", "Int value 5", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, ValuesI[5]),0,0,0,0,0,0,0,0,0,0,0);
  1002. laAddIntProperty(pc, "valuei6", "Value", "Int value 6", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, ValuesI[6]),0,0,0,0,0,0,0,0,0,0,0);
  1003. laAddIntProperty(pc, "valuei7", "Value", "Int value 7", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, ValuesI[7]),0,0,0,0,0,0,0,0,0,0,0);
  1004. laAddFloatProperty(pc, "value0", "Value", "Float value 0", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, Values[0]),0,0,0,0,0,0,0,0,0,0,0);
  1005. laAddFloatProperty(pc, "value1", "Value", "Float value 1", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, Values[1]),0,0,0,0,0,0,0,0,0,0,0);
  1006. laAddFloatProperty(pc, "value2", "Value", "Float value 2", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, Values[2]),0,0,0,0,0,0,0,0,0,0,0);
  1007. laAddFloatProperty(pc, "value3", "Value", "Float value 3", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, Values[3]),0,0,0,0,0,0,0,0,0,0,0);
  1008. laAddFloatProperty(pc, "value4", "Value", "Float value 4", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, Values[4]),0,0,0,0,0,0,0,0,0,0,0);
  1009. laAddFloatProperty(pc, "value5", "Value", "Float value 5", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, Values[5]),0,0,0,0,0,0,0,0,0,0,0);
  1010. laAddFloatProperty(pc, "value6", "Value", "Float value 6", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, Values[6]),0,0,0,0,0,0,0,0,0,0,0);
  1011. laAddFloatProperty(pc, "value7", "Value", "Float value 7", 0,0,0,0,0,0,0,0,offsetof(laValuesNode, Values[7]),0,0,0,0,0,0,0,0,0,0,0);
  1012. p=laAddEnumProperty(pc,"valuee0","SW","Enum Value 0",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, ValuesE[0]),0,0,0,0,0,0,0,0,0,0);la_AddValuesNodeEnumValue(p);
  1013. p=laAddEnumProperty(pc,"valuee1","SW","Enum Value 1",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, ValuesE[1]),0,0,0,0,0,0,0,0,0,0);la_AddValuesNodeEnumValue(p);
  1014. p=laAddEnumProperty(pc,"valuee2","SW","Enum Value 2",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, ValuesE[2]),0,0,0,0,0,0,0,0,0,0);la_AddValuesNodeEnumValue(p);
  1015. p=laAddEnumProperty(pc,"valuee3","SW","Enum Value 3",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, ValuesE[3]),0,0,0,0,0,0,0,0,0,0);la_AddValuesNodeEnumValue(p);
  1016. p=laAddEnumProperty(pc,"valuee4","SW","Enum Value 4",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, ValuesE[4]),0,0,0,0,0,0,0,0,0,0);la_AddValuesNodeEnumValue(p);
  1017. p=laAddEnumProperty(pc,"valuee5","SW","Enum Value 5",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, ValuesE[5]),0,0,0,0,0,0,0,0,0,0);la_AddValuesNodeEnumValue(p);
  1018. p=laAddEnumProperty(pc,"valuee6","SW","Enum Value 6",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, ValuesE[6]),0,0,0,0,0,0,0,0,0,0);la_AddValuesNodeEnumValue(p);
  1019. p=laAddEnumProperty(pc,"valuee7","SW","Enum Value 7",LA_WIDGET_ENUM_CYCLE,0,0,0,0,offsetof(laValuesNode, ValuesE[7]),0,0,0,0,0,0,0,0,0,0);la_AddValuesNodeEnumValue(p);
  1020. pc=laAddPropertyContainer("la_matrix_node", "Matrix", "Matrix node",0,laui_MatrixNode,sizeof(laMatrixNode),0,0,1);
  1021. LA_PC_IDN_MATRIX=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  1022. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  1023. laAddSubGroup(pc,"in_l", "L","Left input","la_in_socket",0,0,0,offsetof(laMatrixNode, InL),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1024. laAddSubGroup(pc,"in_r", "R","Right input","la_in_socket",0,0,0,offsetof(laMatrixNode, InR),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1025. laAddSubGroup(pc,"out", "Out","Output value","la_out_socket",0,0,0,offsetof(laMatrixNode, Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1026. p=laAddEnumProperty(pc,"operation", "Operation", "Operation", 0,0,0,0,0,offsetof(laMatrixNode,Operation),0,0,0,0,0,0,0,0,0,0);
  1027. laAddEnumItemAs(p,"MUL", "Multiply", "L x R", LA_MATRIX_NODE_OP_MUL, 0);
  1028. laAddEnumItemAs(p,"INV", "Invert", "Invert L or R", LA_MATRIX_NODE_OP_INV, 0);
  1029. #define REGISTER_MATH_NODE\
  1030. laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);\
  1031. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);\
  1032. laAddFloatProperty(pc, "vl", "L", "Left value", 0,0,0,0,0,0,0,0,offsetof(laMathNode, ValueL),0,0,0,0,0,0,0,0,0,0,0);\
  1033. laAddFloatProperty(pc, "vr", "R", "Right value", 0,0,0,0,0,0,0,0,offsetof(laMathNode, ValueR),0,0,0,0,0,0,0,0,0,0,0);\
  1034. laAddSubGroup(pc,"in_l", "L","Left input","la_in_socket",0,0,0,offsetof(laMathNode, InL),0,0,0,0,0,0,0,LA_UDF_SINGLE);\
  1035. laAddSubGroup(pc,"in_r", "R","Right input","la_in_socket",0,0,0,offsetof(laMathNode, InR),0,0,0,0,0,0,0,LA_UDF_SINGLE);\
  1036. laAddSubGroup(pc,"out", "Out","Output value","la_out_socket",0,0,0,offsetof(laMathNode, Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);\
  1037. laAddSubGroup(pc,"out_int", "Out Int","Output value in Integer","la_out_socket",0,0,0,offsetof(laMathNode, OutInt),0,0,0,0,0,0,0,LA_UDF_SINGLE);\
  1038. p=laAddEnumProperty(pc,"operation", "Operation", "Operation", 0,0,0,0,0,offsetof(laMathNode, Operation),0,0,0,0,0,0,0,0,0,0);\
  1039. laAddEnumItemAs(p,"ADD", "Add", "L + R", LA_MATH_NODE_OP_ADD, 0);\
  1040. laAddEnumItemAs(p,"SUB", "Subtract", "L - R", LA_MATH_NODE_OP_SUB, 0);\
  1041. laAddEnumItemAs(p,"MUL", "Multiply", "L x R", LA_MATH_NODE_OP_MUL, 0);\
  1042. laAddEnumItemAs(p,"DIV", "Divide", "L / R", LA_MATH_NODE_OP_DIV, 0);\
  1043. laAddEnumItemAs(p,"POW", "Power", "pow(L,R)", LA_MATH_NODE_OP_POW, 0);\
  1044. laAddEnumItemAs(p,"LOG", "Log", "log(L)base(R)", LA_MATH_NODE_OP_LOG, 0);\
  1045. laAddEnumItemAs(p,"SIN", "Sine", "sin(L)", LA_MATH_NODE_OP_SIN, 0);\
  1046. laAddEnumItemAs(p,"COS", "Cosine", "cos(L)", LA_MATH_NODE_OP_COS, 0);\
  1047. laAddEnumItemAs(p,"TAN", "Tangent", "tan(L)", LA_MATH_NODE_OP_TAN, 0);\
  1048. laAddEnumItemAs(p,"ASIN", "Arcsin", "asin(L)", LA_MATH_NODE_OP_ASIN, 0);\
  1049. laAddEnumItemAs(p,"ACOS", "Arccosine", "acos(L)", LA_MATH_NODE_OP_ACOS, 0);\
  1050. laAddEnumItemAs(p,"ATAN", "Arctangent", "atan(L)", LA_MATH_NODE_OP_ATAN, 0);\
  1051. laAddEnumItemAs(p,"ATAN2", "Atan2", "atan2(L,R) where L or R can be zero", LA_MATH_NODE_OP_ATAN2, 0);\
  1052. laAddEnumItemAs(p,"MOD", "Mod", "L \% R", LA_MATH_NODE_OP_MOD, 0);
  1053. pc=laAddPropertyContainer("la_math_node", "Math", "Math node",0,laui_MathNode,sizeof(laMathNode),0,0,1); LA_PC_IDN_MATH=pc; REGISTER_MATH_NODE
  1054. pc=laAddPropertyContainer("la_small_math_node", "Small Math", "Small Math node",0,laui_SmallMathNode,sizeof(laMathNode),0,0,1); LA_PC_IDN_SMALL_MATH=pc; REGISTER_MATH_NODE
  1055. pc=laAddPropertyContainer("la_mapper_node", "Mapper", "Mapper node",0,laui_MapperNode,sizeof(laMapperNode),0,0,1);
  1056. LA_PC_IDN_MAPPER=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  1057. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  1058. laAddSubGroup(pc,"in", "In","Input value","la_in_socket",0,0,0,offsetof(laMapperNode, In),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1059. laAddSubGroup(pc,"out", "Out","Output value","la_out_socket",0,0,0,offsetof(laMapperNode, Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1060. laAddSubGroup(pc,"mapper", "Mapper","Value mapper","la_value_mapper",0,LA_WIDGET_MAPPER,0,offsetof(laMapperNode, Mapper),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1061. p=laAddEnumProperty(pc,"clamp", "Clamp", "Clamp output", LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(laMapperNode,Clamp),0,0,0,0,0,0,0,0,0,0);
  1062. laAddEnumItemAs(p,"NONE", "None", "Don't clamp output", 0, 0);
  1063. laAddEnumItemAs(p,"CLAMP", "Clamp", "Clamp output to specified range", 1, 0);
  1064. pc=laAddPropertyContainer("la_random_node", "Random", "Random node",0,laui_RandomNode,sizeof(laRandomNode),0,0,1);
  1065. LA_PC_IDN_RANDOM=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  1066. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  1067. laAddSubGroup(pc,"out", "Out","Output value","la_out_socket",0,0,0,offsetof(laRandomNode, Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1068. laAddFloatProperty(pc, "range", "Range", "Range of the random values", 0,0,0,0,0,0,0,0,offsetof(laRandomNode, Min),0,0,2,0,0,0,0,0,0,0,0);
  1069. pc=laAddPropertyContainer("la_vector_math_node", "Vector Math", "Math node",0,laui_VectorMathNode,sizeof(laVectorMathNode),0,0,1);
  1070. LA_PC_IDN_VECTOR_MATH=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  1071. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  1072. laAddSubGroup(pc,"in_l", "L","Left input","la_in_socket",0,0,0,offsetof(laVectorMathNode, InL),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1073. laAddSubGroup(pc,"in_r", "R","Right input","la_in_socket",0,0,0,offsetof(laVectorMathNode, InR),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1074. laAddSubGroup(pc,"out", "Out","Output value","la_out_socket",0,0,0,offsetof(laVectorMathNode, Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1075. p=laAddEnumProperty(pc,"operation", "Operation", "Operation", 0,0,0,0,0,offsetof(laVectorMathNode, Operation),0,0,0,0,0,0,0,0,0,0);
  1076. laAddEnumItemAs(p,"ADD", "Add", "L + R", LA_VECTOR_MATH_OP_ADD, 0);
  1077. laAddEnumItemAs(p,"SUB", "Subtract", "L - R", LA_VECTOR_MATH_OP_SUB, 0);
  1078. laAddEnumItemAs(p,"MUL", "Multiply (component)", "L x R (component)", LA_VECTOR_MATH_OP_MUL, 0);
  1079. laAddEnumItemAs(p,"DIV", "Divide (component)", "L / R (component)", LA_VECTOR_MATH_OP_DIV, 0);
  1080. laAddEnumItemAs(p,"CROSS", "Cross", "L x R", LA_VECTOR_MATH_OP_CROSS, 0);
  1081. laAddEnumItemAs(p,"DOT", "Dot", "L . R", LA_VECTOR_MATH_OP_DOT, 0);
  1082. laAddEnumItemAs(p,"POW", "Power", "pow(L,R)", LA_VECTOR_MATH_OP_POW, 0);
  1083. laAddEnumItemAs(p,"LOG", "Log", "log(L)base(R)", LA_VECTOR_MATH_OP_LOG, 0);
  1084. laAddEnumItemAs(p,"NORM", "Normalize", "Normalize(L)", LA_VECTOR_MATH_OP_NORMALIZE, 0);
  1085. pc=laAddPropertyContainer("la_comment_node", "Comment", "Comment",0,laui_CommentNode,sizeof(laCommentNode),0,0,1);
  1086. LA_PC_IDN_COMMENT=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  1087. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  1088. laAddStringProperty(pc,"content","Content","Content of the comment",LA_WIDGET_STRING_MULTI,0,0,0,1,offsetof(laCommentNode,Content),0,0,0,0,0);
  1089. pc=laAddPropertyContainer("la_rgb_to_okhsl_node", "RGB 2 OKHSL", "RGB color to OKHSL values",0,laui_RGB2OKHSLNode,sizeof(laRGB2OKHSLNode),0,0,1);
  1090. LA_PC_IDN_RGB2OKHSL=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  1091. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  1092. laAddSubGroup(pc,"in", "In","Input color","la_in_socket",0,0,0,offsetof(laRGB2OKHSLNode, In),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1093. laAddSubGroup(pc,"out_h", "H","Hue","la_out_socket",0,0,0,offsetof(laRGB2OKHSLNode, OutH),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1094. laAddSubGroup(pc,"out_s", "S","Chroma","la_out_socket",0,0,0,offsetof(laRGB2OKHSLNode, OutS),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1095. laAddSubGroup(pc,"out_l", "L","Brightness","la_out_socket",0,0,0,offsetof(laRGB2OKHSLNode, OutL),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1096. laAddFloatProperty(pc, "color", "Color", "Default color", LA_WIDGET_FLOAT_COLOR,0,0,0,0,0,0,0,offsetof(laRGB2OKHSLNode, RGB),0,0,3,0,0,0,0,0,0,0,0);
  1097. pc=laAddPropertyContainer("la_okhsl_to_rgb_node", "OKHSL 2 RGB", "OKHSL values to RGB color",0,laui_OKHSL2RGBNode,sizeof(laOKHSL2RGBNode),0,0,1);
  1098. LA_PC_IDN_OKHSL2RGB=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  1099. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  1100. laAddSubGroup(pc,"out", "Out","Output color","la_out_socket",0,0,0,offsetof(laOKHSL2RGBNode, Out),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1101. laAddSubGroup(pc,"in_h", "H","Hue","la_in_socket",0,0,0,offsetof(laOKHSL2RGBNode, InH),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1102. laAddSubGroup(pc,"in_s", "S","Chroma","la_in_socket",0,0,0,offsetof(laOKHSL2RGBNode, InS),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1103. laAddSubGroup(pc,"in_l", "L","Brightness","la_in_socket",0,0,0,offsetof(laOKHSL2RGBNode, InL),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  1104. typedef laMathNode laSmallMathNode;
  1105. LA_IDN_REGISTER("Controller",L'🕹',LA_IDN_CONTROLLER,LA_PC_IDN_CONTROLLER, IDN_ControllerInit, IDN_ControllerDestroy, IDN_ControllerVisit, IDN_ControllerEval, laInputControllerNode);
  1106. LA_IDN_REGISTER("Visualizer",L'🔍',LA_IDN_VISUALIZER,LA_PC_IDN_VISUALIZER, IDN_InputVisualizeInit, IDN_InputVisualizeDestroy, IDN_InputVisualizeVisit, IDN_InputVisualizerEval, laInputVisualizerNode);
  1107. LA_IDN_REGISTER("Split",L'⚟',LA_IDN_SPLIT,LA_PC_IDN_SPLIT, IDN_SplitInit, IDN_SplitDestroy, IDN_SplitVisit, IDN_SplitEval, laSplitNode);
  1108. LA_IDN_REGISTER("Switch",L'🚦',LA_IDN_SWITCH,LA_PC_IDN_SWITCH, IDN_SwitchInit, IDN_SwitchDestroy, IDN_SwitchVisit, IDN_SwitchEval, laSwitchNode);
  1109. LA_IDN_REGISTER("Combine",L'⚞',LA_IDN_COMBINE,LA_PC_IDN_COMBINE, IDN_CombineInit, IDN_CombineDestroy, IDN_CombineVisit, IDN_CombineEval, laCombineNode);
  1110. LA_IDN_REGISTER("Values",0,LA_IDN_VALUES,LA_PC_IDN_VALUES, IDN_ValuesInit, IDN_ValuesDestroy, IDN_ValuesVisit, IDN_ValuesEval, laValuesNode);
  1111. LA_IDN_REGISTER("Matrix",0,LA_IDN_MATRIX,LA_PC_IDN_MATRIX, IDN_MatrixInit, IDN_MatrixDestroy, IDN_MatrixVisit, IDN_MatrixEval, laMatrixNode);
  1112. LA_IDN_REGISTER("Math",0,LA_IDN_MATH,LA_PC_IDN_MATH, IDN_MathInit, IDN_MathDestroy, IDN_MathVisit, IDN_MathEval, laMathNode);
  1113. LA_IDN_REGISTER("Small Math",0,LA_IDN_SMALL_MATH,LA_PC_IDN_SMALL_MATH, IDN_MathInit, IDN_MathDestroy, IDN_MathVisit, IDN_MathEval, laSmallMathNode);
  1114. LA_IDN_REGISTER("Mapper",0,LA_IDN_MAPPER,LA_PC_IDN_MAPPER, IDN_MapperInit, IDN_MapperDestroy, IDN_MapperVisit, IDN_MapperEval, laMapperNode);
  1115. LA_IDN_REGISTER("Random",0,LA_IDN_RANDOM,LA_PC_IDN_RANDOM, IDN_RandomInit, IDN_RandomDestroy, IDN_RandomVisit, IDN_RandomEval, laRandomNode);
  1116. LA_IDN_REGISTER("Vector Math",0,LA_IDN_VECTOR_MATH,LA_PC_IDN_VECTOR_MATH, IDN_VectorMathInit, IDN_VectorMathDestroy, IDN_VectorMathVisit, IDN_VectorMathEval, laVectorMathNode);
  1117. LA_IDN_REGISTER("Comment",0,LA_IDN_COMMENT,LA_PC_IDN_COMMENT, IDN_CommentInit, IDN_CommentDestroy, IDN_CommentVisit, IDN_CommentEval, laCommentNode);
  1118. LA_IDN_REGISTER("RGB to OKHSL",0,LA_IDN_RGB2OKHSL,LA_PC_IDN_RGB2OKHSL, IDN_RGB2OKHSLInit, IDN_RGB2OKHSLDestroy, IDN_RGB2OKHSLVisit, IDN_RGB2OKHSLEval, laRGB2OKHSLNode);
  1119. LA_IDN_REGISTER("OKHSL to RGB",0,LA_IDN_OKHSL2RGB,LA_PC_IDN_OKHSL2RGB, IDN_OKHSL2RGBInit, IDN_OKHSL2RGBDestroy, IDN_OKHSL2RGBVisit, IDN_OKHSL2RGBEval, laOKHSL2RGBNode);
  1120. LA_NODE_CATEGORY_INPUT=laAddNodeCategory("Input",0,LA_RACK_TYPE_INPUT);
  1121. LA_NODE_CATEGORY_MATH=laAddNodeCategory("Math",0,LA_RACK_TYPE_ALL);
  1122. LA_NODE_CATEGORY_COLOR=laAddNodeCategory("Color",0,LA_RACK_TYPE_ALL);
  1123. LA_NODE_CATEGORY_ROUTE=laAddNodeCategory("Route",0,LA_RACK_TYPE_ALL);
  1124. LA_NODE_CATEGORY_AUX=laAddNodeCategory("Auxiliary",0,LA_RACK_TYPE_ALL);
  1125. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_INPUT, &LA_IDN_CONTROLLER,0);
  1126. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_MATH, &LA_IDN_MATH, &LA_IDN_SMALL_MATH,&LA_IDN_VECTOR_MATH,&LA_IDN_MAPPER,&LA_IDN_RANDOM,&LA_IDN_MATRIX,0);
  1127. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_ROUTE, &LA_IDN_SPLIT, &LA_IDN_SWITCH, &LA_IDN_COMBINE, &LA_IDN_VALUES, &LA_IDN_VISUALIZER,0);
  1128. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_AUX, &LA_IDN_COMMENT,0);
  1129. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_COLOR, &LA_IDN_RGB2OKHSL, &LA_IDN_OKHSL2RGB,0);
  1130. MAIN.tNodeIn=laCreateInSocket("TIN",0);
  1131. MAIN.tNodeOut=laCreateOutSocket(0,"TOUT",0);
  1132. }
  1133. void laMappingRequestRebuild(){ MAIN.InputMapping->NeedRebuild=1; }
  1134. void laMappingRequestEval(){ MAIN.InputMapping->NeedEval=1; }
  1135. int la_RunInputMapping(){
  1136. MAIN.InputMapping->NeedEval = 0;
  1137. for(laListItemPointer*lip=MAIN.InputMapping->Eval.pFirst;lip;lip=lip->pNext){
  1138. laBaseNode* n=lip->p; if(!n->InitDone){ n->Type->Init(n,1); n->InitDone=1; } n->Type->Eval(n);
  1139. }
  1140. return 1;
  1141. }
  1142. int la_RebuildInputMapping(){
  1143. MAIN.InputMapping->NeedRebuild = 0;
  1144. while(lstPopPointer(&MAIN.InputMapping->Eval));
  1145. laListHandle pending={0}; laRackPage* rp=MAIN.InputMapping->CurrentPage; if(!rp)return LA_DAG_FLAG_PERM;
  1146. for(laNodeRack* ir=rp->Racks.pFirst;ir;ir=ir->Item.pNext){
  1147. for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ lstAppendPointer(&pending,bn); bn->Eval=0; }
  1148. }
  1149. laBaseNode*n;int result=LA_DAG_FLAG_PERM; laListItemPointer*NextLip;
  1150. for(laListItemPointer*lip=pending.pFirst;lip;lip=NextLip){ n=lip->p; NextLip=lip->pNext;
  1151. if(n->Eval&LA_DAG_FLAG_PERM) continue;
  1152. result=n->Type->Visit(n,&MAIN.InputMapping->Eval); if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&pending)); break; }
  1153. }
  1154. if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&MAIN.InputMapping->Eval)); return LA_DAG_FLAG_ERR; }
  1155. return LA_DAG_FLAG_PERM;
  1156. }
  1157. //==================================================================================================
  1158. laNodeOutSocket* laCreateOutSocket(void* NodeParentOptional, char* label, int DataType){
  1159. laNodeOutSocket* os=memAcquire(sizeof(laNodeOutSocket));
  1160. strSafeSet(&os->Label, label); os->DataType = DataType; os->Parent=NodeParentOptional;
  1161. return os;
  1162. }
  1163. laNodeInSocket* laCreateInSocket(char* label, int DataType){
  1164. laNodeInSocket* is=memAcquire(sizeof(laNodeInSocket));
  1165. strSafeSet(&is->Label, label); is->DataType = DataType;
  1166. return is;
  1167. }
  1168. void laDestroyInSocket(laNodeInSocket* s){ strSafeDestroy(&s->Label); memLeave(s); }
  1169. void laDestroyOutSocket(laNodeOutSocket* s){ strSafeDestroy(&s->Label); memLeave(s); }
  1170. laNodeCategory* laAddNodeCategory(char* Name,laUiDefineFunc* Ui,int ForRackTypes){
  1171. laNodeCategory* nc=memAcquire(sizeof(laNodeCategory));
  1172. lstAppendItem(&MAIN.NodeCategories,nc);
  1173. strSafeSet(&nc->Name, Name); nc->Ui=Ui; nc->For=ForRackTypes;
  1174. return nc;
  1175. }
  1176. void laNodeCategoryAddNodeTypes(laNodeCategory* nc, ...){
  1177. va_list list; va_start(list,nc);
  1178. laBaseNodeType* nt;
  1179. while(nt=va_arg(list,laBaseNodeType*)){
  1180. lstAppendPointer(&nc->NodeTypes, nt);
  1181. }
  1182. va_end(list);
  1183. }