*/}}

la_nodes_basic.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  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. laPropContainer* LA_PC_IDN_GENERIC;
  15. laPropContainer* LA_PC_IDN_KEYBOARD;
  16. laPropContainer* LA_PC_IDN_MOUSE;
  17. laPropContainer* LA_PC_IDN_CONTROLLER;
  18. laPropContainer* LA_PC_IDN_VISUALIZER;
  19. laPropContainer* LA_PC_IDN_SPLIT;
  20. laPropContainer* LA_PC_IDN_SWITCH;
  21. laPropContainer* LA_PC_IDN_COMBINE;
  22. laPropContainer* LA_PC_IDN_VALUES;
  23. laPropContainer* LA_PC_IDN_MATRIX;
  24. laPropContainer* LA_PC_IDN_MATH;
  25. laNodeCategory* LA_NODE_CATEGORY_INPUT;
  26. laNodeCategory* LA_NODE_CATEGORY_MATH;
  27. laNodeCategory* LA_NODE_CATEGORY_ROUTE;
  28. laNodeCategory* LA_NODE_CATEGORY_DRIVER;
  29. #define LA_IDN_CONTROLLER_RESET_SOCKET(ns)\
  30. {ns->IntVal[0]=0; ns->Out->DataType=LA_PROP_INT; ns->Offset=0; ns->Out->Data=&ns->IntVal;}
  31. void IDN_ControllerInit(laInputControllerNode* n){
  32. for(int i=0;i<8;i++){ n->Sockets[i].Out=laCreateOutSocket(n, "out", 0); n->Sockets[i].Parent=n; }
  33. strSafeSet(&n->Base.Name,"Controller Output");
  34. }
  35. void IDN_ControllerDestroy(laInputControllerNode* n){
  36. for(int i=0;i<8;i++){ laDestroyOutSocket(n->Sockets[i].Out); }
  37. strSafeDestroy(&n->Base.Name);
  38. }
  39. int IDN_ControllerVisit(laInputControllerNode* n, laListHandle* l){
  40. laController* c=la_FindControllerWithID(n->UserID);
  41. 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; }
  42. else{
  43. for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i];
  44. if(!ns->Which || !ns->Which->Ptr){ LA_IDN_CONTROLLER_RESET_SOCKET(ns); continue; }
  45. laPropContainer*pc=la_EnsureSubTarget(LA_PROP_CONTROLLER, c);
  46. laProp* p=la_PropLookup(&pc->Props, n->Sockets[i].Which->Ptr);
  47. if((!p)||(!p->Offset)||
  48. ((p->PropertyType!=LA_PROP_INT)&&(p->PropertyType!=LA_PROP_ENUM)&&
  49. (p->PropertyType!=(LA_PROP_INT|LA_PROP_ARRAY))&&(p->PropertyType!=(LA_PROP_ENUM|LA_PROP_ARRAY)))){ LA_IDN_CONTROLLER_RESET_SOCKET(ns); continue; }
  50. if(p->PropertyType==LA_PROP_INT){ ns->Out->DataType=LA_PROP_FLOAT; ns->Out->Data=&ns->RealVal; ns->Out->ArrLen=1; }
  51. 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; }
  52. elif(p->PropertyType==LA_PROP_ENUM){ ns->Out->DataType=LA_PROP_ENUM; ns->Out->Data=&ns->IntVal; ns->Out->ArrLen=1; }
  53. 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; }
  54. ns->Offset=p->Offset;
  55. }
  56. }
  57. n->Base.Eval=LA_DAG_FLAG_PERM;
  58. lstAppendPointer(l, n);
  59. return LA_DAG_FLAG_PERM;
  60. }
  61. int IDN_ControllerEval(laInputControllerNode* n){
  62. laNotifyInstanceUsers(n);
  63. laController* c=la_FindControllerWithID(n->UserID); if(!c){
  64. for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i]; LA_IDN_CONTROLLER_RESET_SOCKET(ns); } return 1;
  65. }
  66. for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i];
  67. int *addr=((char*)c)+ns->Offset; char* addc=addr;
  68. if(ns->Out->DataType==LA_PROP_FLOAT){ ns->RealVal[0]=(real)(*addr)/32767.0; }
  69. 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; }
  70. elif(ns->Out->DataType==LA_PROP_ENUM){ ns->IntVal[0]=(*addc); }
  71. elif(ns->Out->DataType==(LA_PROP_ENUM|LA_PROP_ARRAY)){ for(int a=0;a<ns->Out->ArrLen;a++) ns->IntVal[a]=addc[a]; }
  72. }
  73. return 1;
  74. }
  75. void laui_ControllerNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  76. laColumn* c=laFirstColumn(uil); laInputControllerNode*n=This->EndInstance;
  77. laColumn* cl,*cr;
  78. LA_BASE_NODE_HEADER(uil,c,This);
  79. laSplitColumn(uil,c,0.3); cl=laLeftColumn(c,0); cr=laRightColumn(c,0);
  80. laUiItem* b=laBeginRow(uil,c,0,0);
  81. laShowItem(uil,c,This,"base.name")->Expand=1;
  82. laShowItem(uil,c,This,"user_id");
  83. laEndRow(uil,b);
  84. char* buf[128],buf2[128];
  85. for(int i=0;i<8;i++){
  86. sprintf(buf,"out%d.which",i); laShowItem(uil,cl,This,buf);
  87. laUiItem* b=laBeginRow(uil,cr,0,0);
  88. sprintf(buf2,"out%d.out.data_type",i);
  89. laUiItem* b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,buf2),laIntExpression(LA_PROP_FLOAT)));{
  90. sprintf(buf,"out%d.axis",i); laShowItem(uil,cr,This,buf)->Expand=1;
  91. }laElse(uil,b2);{
  92. laUiItem* b3=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,buf2),laIntExpression(LA_PROP_FLOAT|LA_PROP_ARRAY)));{
  93. 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;
  94. }laElse(uil,b3);{
  95. sprintf(buf,"out%d.switch",i); laUiItem* sui=laShowItem(uil,cr,This,buf);sui->Expand=1;sui->Flags|=LA_UI_FLAGS_TRANSPOSE;
  96. }laEndCondition(uil,b3);
  97. }laEndCondition(uil,b2);
  98. sprintf(buf,"out%d.out",i); laShowNodeSocket(uil,cr,This,buf,0);
  99. laEndRow(uil,b);
  100. }
  101. }
  102. void IDN_InputVisualizeInit(laInputVisualizerNode* n){
  103. n->In=laCreateInSocket("IN", 0);
  104. strSafeSet(&n->Base.Name,"Input Visualizer");
  105. }
  106. void IDN_InputVisualizeDestroy(laInputVisualizerNode* n){
  107. laDestroyInSocket(n->In);
  108. strSafeDestroy(&n->Base.Name);
  109. }
  110. int IDN_InputVisualizeVisit(laInputVisualizerNode* n, laListHandle* l){
  111. n->Base.Eval=LA_DAG_FLAG_TEMP;
  112. if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* sn=n->In->Source->Parent;LA_VISIT_NODE(sn); }
  113. n->Base.Eval=LA_DAG_FLAG_PERM;
  114. lstAppendPointer(l, n);
  115. return LA_DAG_FLAG_PERM;
  116. }
  117. int IDN_InputVisualizerEval(laInputVisualizerNode* n){
  118. if(!n->In->Source) return 0;
  119. laNodeOutSocket* os=n->In->Source; int arrlen=1;
  120. switch(os->DataType){
  121. case LA_PROP_FLOAT|LA_PROP_ARRAY:
  122. case LA_PROP_FLOAT: if(os->ArrLen)arrlen=os->ArrLen; memcpy(n->RealVal,os->Data,sizeof(real)*arrlen); n->In->ArrLen=arrlen; break;
  123. case LA_PROP_ENUM|LA_PROP_ARRAY:
  124. case LA_PROP_ENUM: if(os->ArrLen)arrlen=os->ArrLen; memcpy(n->IntVal,os->Data,sizeof(int)*arrlen); n->In->ArrLen=arrlen; break;
  125. default: n->IntVal[0]=0; n->In->ArrLen=1; break;
  126. }
  127. n->In->DataType=os->DataType;
  128. laNotifyInstanceUsers(n);
  129. return 1;
  130. }
  131. void laui_InputVisualizeNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  132. laColumn* c=laFirstColumn(uil); laInputVisualizerNode*n=This->EndInstance;
  133. LA_BASE_NODE_HEADER(uil,c,This);
  134. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  135. laShowNodeSocket(uil,cl,This,"in",0);
  136. laUiItem* b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,"in.data_type"),laIntExpression(LA_PROP_FLOAT)));{
  137. laShowItem(uil,cr,This,"axis");
  138. }laElse(uil,b2);{
  139. laUiItem* b3=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,"in.data_type"),laIntExpression(LA_PROP_FLOAT|LA_PROP_ARRAY)));{
  140. laUiItem* aui=laShowItem(uil,cr,This,"axis2d");
  141. }laElse(uil,b3);{
  142. laUiItem* sui=laShowItem(uil,cr,This,"switch");
  143. }laEndCondition(uil,b3);
  144. }laEndCondition(uil,b2);
  145. }
  146. void IDN_SplitInit(laSplitNode* n){
  147. n->In=laCreateInSocket("in", 0); strSafeSet(&n->Base.Name,"Split");
  148. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->Out[i].Out=laCreateOutSocket(n,str,0); }
  149. }
  150. void IDN_SplitDestroy(laSplitNode* n){
  151. laDestroyInSocket(n->In); strSafeDestroy(&n->Base.Name);
  152. for(int i=0;i<8;i++){ laDestroyOutSocket(n->Out[i].Out); }
  153. }
  154. int IDN_SplitVisit(laSplitNode* n, laListHandle* l){
  155. LA_GUARD_THIS_NODE(n);
  156. if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* sn=n->In->Source->Parent; LA_VISIT_NODE(sn); }
  157. n->Base.Eval=LA_DAG_FLAG_PERM;
  158. lstAppendPointer(l, n);
  159. return LA_DAG_FLAG_PERM;
  160. }
  161. int IDN_SplitEval(laSplitNode* n){
  162. if(!n->In->Source) return 0;
  163. laNodeOutSocket* os=n->In->Source; int arrlen=1;
  164. switch(os->DataType){
  165. case LA_PROP_FLOAT|LA_PROP_ARRAY:
  166. case LA_PROP_FLOAT: if(os->ArrLen) n->ArrLen=os->ArrLen;
  167. 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]; }
  168. memcpy(n->RealVal,os->Data,sizeof(real)*n->ArrLen); n->In->ArrLen=arrlen; break;
  169. case LA_PROP_ENUM|LA_PROP_ARRAY:
  170. case LA_PROP_ENUM: if(os->ArrLen) n->ArrLen=os->ArrLen;
  171. 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]; }
  172. memcpy(n->IntVal,os->Data,sizeof(int)*n->ArrLen); n->In->ArrLen=arrlen; break;
  173. default:
  174. 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]; }
  175. n->IntVal[0]=0; n->In->ArrLen=1; break;
  176. }
  177. n->In->DataType=os->DataType;
  178. return 1;
  179. }
  180. void laui_SplitNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  181. laColumn* c=laFirstColumn(uil); laSplitNode*n=This->EndInstance;
  182. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  183. LA_BASE_NODE_HEADER(uil,c,This);
  184. laUiItem* b=laBeginRow(uil,c,0,0);
  185. laShowNodeSocket(uil,c,This,"in",0);
  186. laShowItemFull(uil,c,This,"array_length",LA_WIDGET_INT_PLAIN,0,0,0);
  187. laShowLabel(uil,c,"🡲",0,0)->Expand=1;
  188. for(int i=0;i<8;i++){
  189. char* buf[128]; sprintf(buf,"out%d.out",i); laShowNodeSocket(uil,cr,This,buf,0);
  190. }
  191. laEndRow(uil,b);
  192. }
  193. void IDN_SwitchInit(laSwitchNode* n){
  194. n->SwitchIn=laCreateInSocket("sw in",0); n->Out=laCreateOutSocket(n,"out",0); strSafeSet(&n->Base.Name,"Switch");
  195. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->In[i].In=laCreateInSocket(n,str); }
  196. }
  197. void IDN_SwitchDestroy(laSwitchNode* n){
  198. laDestroyInSocket(n->SwitchIn); laDestroyOutSocket(n->Out); strSafeDestroy(&n->Base.Name);
  199. for(int i=0;i<8;i++){ laDestroyInSocket(n->In[i].In); }
  200. }
  201. int IDN_SwitchVisit(laSwitchNode* n, laListHandle* l){
  202. LA_GUARD_THIS_NODE(n);
  203. for(int i=0;i<8;i++){
  204. if(n->In[i].In->Source){ laBaseNode* sn=n->In[i].In->Source->Parent; LA_VISIT_NODE(sn); }
  205. }
  206. laBaseNode* sw=n->SwitchIn->Source?n->SwitchIn->Source->Parent:0; if(sw){ LA_VISIT_NODE(sw); }
  207. n->Base.Eval=LA_DAG_FLAG_PERM;
  208. lstAppendPointer(l, n);
  209. return LA_DAG_FLAG_PERM;
  210. }
  211. int IDN_SwitchEval(laSwitchNode* n){
  212. int sw=n->Switch;
  213. if(n->SwitchIn->Source){ laNodeOutSocket* os=n->SwitchIn->Source; int* id; real* fd;
  214. switch(os->DataType){
  215. case LA_PROP_ARRAY|LA_PROP_ENUM:
  216. id=os->Data; for(int i=0;i<os->ArrLen;i++){ if(id[i]){sw=i; break;} } break;
  217. case LA_PROP_ENUM: case LA_PROP_INT: case LA_PROP_INT|LA_PROP_ARRAY:
  218. id=os->Data; sw=*id; break;
  219. case LA_PROP_FLOAT: case LA_PROP_FLOAT|LA_PROP_ARRAY:
  220. fd=os->Data; sw=(int)(*fd); break;
  221. default: sw=0; break;
  222. }
  223. }
  224. TNS_CLAMP(sw,0,7);
  225. laSwitchNodeInSocket *is=&n->In[sw];
  226. 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; }
  227. else{ n->Out->Data=&n->TempVal; n->Out->DataType=LA_PROP_FLOAT; n->Out->ArrLen=1; }
  228. return 1;
  229. }
  230. void laui_SwitchNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  231. laColumn* c=laFirstColumn(uil); laSwitchNode*n=This->EndInstance;
  232. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  233. LA_BASE_NODE_HEADER(uil,c,This);
  234. laUiItem* b=laBeginRow(uil,c,0,0);
  235. for(int i=0;i<8;i++){
  236. char* buf[128]; sprintf(buf,"in%d.in",i); laShowNodeSocket(uil,cr,This,buf,0);
  237. } laShowSeparator(uil,c)->Expand=1;
  238. laEndRow(uil,b);
  239. b=laBeginRow(uil,c,0,0);
  240. laShowItem(uil,c,This,"switch_in");
  241. laUiItem* b2=laOnConditionThat(uil,c,laNot(laPropExpression(This,"switch_in.source")));{
  242. laShowItem(uil,c,This,"switch");
  243. };laEndCondition(uil,b2);
  244. laShowSeparator(uil,c)->Expand=1;
  245. laShowNodeSocket(uil,c,This,"out",0);
  246. laEndRow(uil,b);
  247. }
  248. void IDN_CombineInit(laCombineNode* n){
  249. n->Out=laCreateOutSocket(n,"F",0);n->OutInt=laCreateOutSocket(n,"I",0);n->OutEnum=laCreateOutSocket(n,"E",0); strSafeSet(&n->Base.Name,"Combine");
  250. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->In[i].In=laCreateInSocket(n,str); }
  251. n->Out->Data=n->Values; n->OutInt->Data=n->ValuesI; n->OutEnum->Data=n->ValuesI;
  252. 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;
  253. }
  254. void IDN_CombineDestroy(laCombineNode* n){
  255. laDestroyOutSocket(n->Out);laDestroyOutSocket(n->OutInt);laDestroyOutSocket(n->OutEnum); strSafeDestroy(&n->Base.Name);
  256. for(int i=0;i<8;i++){ laDestroyInSocket(n->In[i].In); }
  257. }
  258. int IDN_CombineVisit(laCombineNode* n, laListHandle* l){
  259. LA_GUARD_THIS_NODE(n);
  260. 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); } }
  261. n->Base.Eval=LA_DAG_FLAG_PERM;
  262. lstAppendPointer(l, n);
  263. return LA_DAG_FLAG_PERM;
  264. }
  265. int IDN_CombineEval(laCombineNode* n){
  266. int maxlen=0;
  267. for(int i=0;i<8;i++){ laNodeInSocket *is=n->In[i].In;
  268. if(LA_SRC_AND_PARENT(is)){
  269. if((is->Source->DataType&LA_PROP_FLOAT) && is->Source->Data){ n->Values[i]=*((real*)is->Source->Data); }
  270. elif((is->Source->DataType&LA_PROP_INT) && is->Source->Data){ n->Values[i]=*((int*)is->Source->Data); }
  271. elif((is->Source->DataType&LA_PROP_ENUM) && is->Source->Data){ n->Values[i]=*((int*)is->Source->Data); }
  272. else n->Values[i]=0;
  273. maxlen=i+1;
  274. }
  275. else n->Values[i]=0;
  276. n->ValuesI[i]=n->Values[i];
  277. }
  278. n->Out->ArrLen=n->OutInt->ArrLen=n->OutEnum->ArrLen=maxlen;
  279. return 1;
  280. }
  281. void laui_CombineNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  282. laColumn* c=laFirstColumn(uil); laCombineNode*n=This->EndInstance;
  283. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,1); cr=laRightColumn(c,0);
  284. LA_BASE_NODE_HEADER(uil,c,This);
  285. laUiItem* b=laBeginRow(uil,c,0,0);
  286. for(int i=0;i<8;i++){
  287. char* buf[128]; sprintf(buf,"in%d.in",i); laShowNodeSocket(uil,cr,This,buf,0);
  288. } laShowSeparator(uil,c)->Expand=1;
  289. laEndRow(uil,b);
  290. b=laBeginRow(uil,c,0,0);
  291. laUiItem* lu=laShowLabel(uil,c,"Combine 🡲",0,0); lu->Expand=1; lu->Flags|=LA_TEXT_ALIGN_RIGHT;
  292. laShowNodeSocket(uil,c,This,"out_enum",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  293. laShowNodeSocket(uil,c,This,"out_int",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  294. laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  295. laEndRow(uil,b);
  296. }
  297. void IDN_ValuesInit(laValuesNode* n){
  298. strSafeSet(&n->Base.Name,"Values");
  299. for(int i=0;i<8;i++){ char str[4]; sprintf(str,"%d",i); n->Out[i].Out=laCreateOutSocket(n,str,0); }
  300. }
  301. void IDN_ValuesDestroy(laValuesNode* n){
  302. strSafeDestroy(&n->Base.Name);
  303. for(int i=0;i<8;i++){ laDestroyOutSocket(n->Out[i].Out); }
  304. }
  305. int IDN_ValuesVisit(laValuesNode* n, laListHandle* l){
  306. LA_GUARD_THIS_NODE(n);
  307. n->Base.Eval=LA_DAG_FLAG_PERM;
  308. lstAppendPointer(l, n);
  309. return LA_DAG_FLAG_PERM;
  310. }
  311. int IDN_ValuesEval(laValuesNode* n){
  312. for(int i=0;i<8;i++){ laNodeOutSocket *is=n->Out[i].Out;
  313. if(n->Modes[i]==LA_VALUES_NODE_FLOAT){ is->Data=&n->Values[i]; is->DataType=LA_PROP_FLOAT; }
  314. if(n->Modes[i]==LA_VALUES_NODE_INT){ is->Data=&n->ValuesI[i]; is->DataType=LA_PROP_INT; }
  315. if(n->Modes[i]==LA_VALUES_NODE_ENUM){ is->Data=&n->ValuesE[i]; is->DataType=LA_PROP_ENUM; }
  316. }
  317. return 1;
  318. }
  319. void laui_ValuesNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  320. laColumn* c=laFirstColumn(uil); laValuesNode*n=This->EndInstance;
  321. laUiItem*b,*b2;
  322. LA_BASE_NODE_HEADER(uil,c,This);
  323. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  324. for(int i=0;i<8;i++){
  325. char* bufm[32]; sprintf(bufm,"mode%d",i); laShowItem(uil,cl,This,bufm);
  326. b=laBeginRow(uil,cr,0,0);
  327. b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,bufm),laIntExpression(LA_VALUES_NODE_FLOAT)));{
  328. char* buf[32]; sprintf(buf,"value%d",i); laShowItem(uil,cr,This,buf)->Expand=1;
  329. }laEndCondition(uil,b2);
  330. b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,bufm),laIntExpression(LA_VALUES_NODE_INT)));{
  331. char* buf[32]; sprintf(buf,"valuei%d",i); laShowItem(uil,cr,This,buf)->Expand=1;
  332. }laEndCondition(uil,b2);
  333. b2=laOnConditionThat(uil,cr,laEqual(laPropExpression(This,bufm),laIntExpression(LA_VALUES_NODE_ENUM)));{
  334. char* buf[32]; sprintf(buf,"valuee%d",i); laUiItem* eui=laShowItem(uil,cr,This,buf); eui->Expand=1; eui->Flags|=LA_UI_FLAGS_HIGHLIGHT;
  335. }laEndCondition(uil,b2);
  336. sprintf(bufm,"out%d.out",i); laShowNodeSocket(uil,cr,This,bufm,0);
  337. laEndRow(uil,b);
  338. }
  339. }
  340. void IDN_MatrixInit(laMatrixNode* n){
  341. strSafeSet(&n->Base.Name,"Matrix");
  342. n->InL=laCreateInSocket("l",0); n->InR=laCreateInSocket("r",0); n->Out=laCreateOutSocket(n,"MAT",LA_PROP_FLOAT|LA_PROP_ARRAY);
  343. n->Out->ArrLen=16; n->Out->Data=n->Mat;
  344. }
  345. void IDN_MatrixDestroy(laMatrixNode* n){
  346. strSafeDestroy(&n->Base.Name);
  347. laDestroyInSocket(n->InL); laDestroyInSocket(n->InR); laDestroyOutSocket(n->Out);
  348. }
  349. int IDN_MatrixVisit(laMatrixNode* n, laListHandle* l){
  350. LA_GUARD_THIS_NODE(n);
  351. if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
  352. if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn); }
  353. n->Base.Eval=LA_DAG_FLAG_PERM;
  354. lstAppendPointer(l, n);
  355. return LA_DAG_FLAG_PERM;
  356. }
  357. int IDN_MatrixEval(laMatrixNode* n){
  358. int hasl=LA_SRC_AND_PARENT(n->InL),hasr=LA_SRC_AND_PARENT(n->InR);
  359. if((!hasl) && (!hasr)){ tnsLoadIdentity44d(n->Mat); return 0; }
  360. if(hasl&&((n->InL->Source->DataType!=(LA_PROP_FLOAT|LA_PROP_ARRAY))||n->InL->Source->ArrLen!=16)){tnsLoadIdentity44d(n->Mat); return 0;}
  361. if(hasr&&((n->InR->Source->DataType!=(LA_PROP_FLOAT|LA_PROP_ARRAY))||n->InR->Source->ArrLen!=16)){tnsLoadIdentity44d(n->Mat); return 0;}
  362. if(n->Operation==LA_MATRIX_NODE_OP_INV){
  363. real* mat; if(hasl)mat=n->InL->Source->Data;else mat=n->InR->Source->Data;
  364. tnsInverse44d(n->Mat, mat);
  365. }else{
  366. if(!hasl) { memcpy(n->Mat,n->InR->Source->Data,sizeof(tnsMatrix44d)); }
  367. elif(!hasr) { memcpy(n->Mat,n->InL->Source->Data,sizeof(tnsMatrix44d)); }
  368. else{
  369. tnsMultiply44d(n->Mat,n->InL->Source->Data,n->InR->Source->Data);
  370. }
  371. }
  372. return 1;
  373. }
  374. void laui_MatrixNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  375. laColumn* c=laFirstColumn(uil); laMatrixNode*n=This->EndInstance;
  376. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  377. laUiItem*b,*b2;
  378. LA_BASE_NODE_HEADER(uil,c,This);
  379. b=laBeginRow(uil,c,0,0);
  380. laShowNodeSocket(uil,c,This,"in_l",0); laShowNodeSocket(uil,c,This,"in_r",0); laShowItem(uil,c,This,"operation");
  381. laShowSeparator(uil,c)->Expand=1; laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  382. laEndRow(uil,b);
  383. }
  384. void IDN_MathInit(laMathNode* n){
  385. strSafeSet(&n->Base.Name,"Math");
  386. n->InL=laCreateInSocket("l",0); n->InR=laCreateInSocket("r",0);
  387. n->Out=laCreateOutSocket(n,"F",LA_PROP_FLOAT); n->OutInt=laCreateOutSocket(n,"I",LA_PROP_INT);
  388. n->Out->Data=&n->Value; n->OutInt->Data=&n->ValueI;
  389. }
  390. void IDN_MathDestroy(laMathNode* n){
  391. strSafeDestroy(&n->Base.Name); laDestroyInSocket(n->InL); laDestroyInSocket(n->InR); laDestroyOutSocket(n->Out); laDestroyOutSocket(n->OutInt);
  392. }
  393. int IDN_MathVisit(laMathNode* n, laListHandle* l){
  394. LA_GUARD_THIS_NODE(n);
  395. if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
  396. if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn); }
  397. n->Base.Eval=LA_DAG_FLAG_PERM;
  398. lstAppendPointer(l, n);
  399. return LA_DAG_FLAG_PERM;
  400. }
  401. #define LA_GET_SRC_AS_FLOAT(var, socket)\
  402. {if(socket->Source->DataType&LA_PROP_FLOAT) var=*((real*)socket->Source->Data);\
  403. if(socket->Source->DataType&(LA_PROP_INT|LA_PROP_ENUM)) var=*((int*)socket->Source->Data);}
  404. int IDN_MathEval(laMathNode* n){
  405. real vl=n->ValueL;real vr=n->ValueR;
  406. int hasl=LA_SRC_AND_PARENT(n->InL),hasr=LA_SRC_AND_PARENT(n->InR);
  407. if(hasl){ LA_GET_SRC_AS_FLOAT(vl,n->InL) } if(hasr){ LA_GET_SRC_AS_FLOAT(vr,n->InR) }
  408. switch(n->Operation){
  409. case LA_MATH_NODE_OP_ADD: default: n->Value=vl+vr; break;
  410. case LA_MATH_NODE_OP_SUB: n->Value=vl-vr; break;
  411. case LA_MATH_NODE_OP_MUL: n->Value=vl*vr; break;
  412. case LA_MATH_NODE_OP_DIV: if(vr)n->Value=vl/vr;else n->Value=0; break;
  413. case LA_MATH_NODE_OP_POW: n->Value=pow(vl,vr); break;
  414. case LA_MATH_NODE_OP_LOG: n->Value=log2(vl)/log2(vr); break;
  415. case LA_MATH_NODE_OP_SIN: n->Value=sin(vl); break;
  416. case LA_MATH_NODE_OP_COS: n->Value=cos(vl); break;
  417. case LA_MATH_NODE_OP_TAN: n->Value=tan(vl); break;
  418. case LA_MATH_NODE_OP_ASIN: n->Value=asin(vl); break;
  419. case LA_MATH_NODE_OP_ACOS: n->Value=acos(vl); break;
  420. case LA_MATH_NODE_OP_ATAN: n->Value=atan(vl); break;
  421. case LA_MATH_NODE_OP_ATAN2: n->Value=atan2(vl,vr); break;
  422. }
  423. n->ValueI=(int)n->Value;
  424. return 1;
  425. }
  426. void laui_MathNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  427. laColumn* c=laFirstColumn(uil); laMathNode*n=This->EndInstance;
  428. laColumn* cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,3); cr=laRightColumn(c,0);
  429. laUiItem*b,*b2;
  430. LA_BASE_NODE_HEADER(uil,c,This);
  431. b=laBeginRow(uil,c,0,0);
  432. 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);
  433. laShowSeparator(uil,c)->Expand=1; laShowItem(uil,c,This,"operation");
  434. laEndRow(uil,b);
  435. b=laBeginRow(uil,c,0,0);
  436. 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);
  437. laShowSeparator(uil,c)->Expand=1;
  438. laShowNodeSocket(uil,c,This,"out_int",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  439. laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  440. laEndRow(uil,b);
  441. }
  442. int OPINV_AddInputMapperPage(laOperator* a, laEvent *e){
  443. laRackPage* dp=memAcquireHyper(sizeof(laRackPage));
  444. strSafeSet(&dp->Name,"New Page");
  445. lstAppendItem(&MAIN.InputMapping->Pages, dp); MAIN.InputMapping->CurrentPage=dp;
  446. laNotifyUsers("la.input_mapping"); laRecordAndPush(0,"la.input_mapping","Add Page", 0);
  447. return LA_FINISHED;
  448. }
  449. int OPINV_AddNodesRack(laOperator* a, laEvent *e){
  450. laRackPage* dp=a->This?a->This->EndInstance:0; if(!dp) return LA_FINISHED;
  451. laNodeRack* ir=memAcquire(sizeof(laNodeRack));
  452. char* type=strGetArgumentString(a->ExtraInstructionsP, "type");
  453. strSafeSet(&ir->Name,"New Rack");
  454. lstAppendItem(&dp->Racks, ir); ir->ParentPage=dp;
  455. if(strSame(type,"DRIVER")){ ir->RackType=LA_RACK_TYPE_DRIVER; laNotifyUsers("la.drivers"); laRecordAndPush(0,"la.drivers","Add rack", 0); }
  456. else{ ir->RackType=LA_RACK_TYPE_INPUT; laNotifyUsers("la.input_mapping"); laRecordAndPush(0,"la.input_mapping","Add rack", 0); }
  457. return LA_FINISHED;
  458. }
  459. int OPINV_RebuildInputMapping(laOperator* a, laEvent *e){
  460. laMappingRequestRebuild();
  461. return LA_FINISHED;
  462. }
  463. laBaseNode* la_CreateNode(laNodeRack* ir, laBaseNodeType* NodeType){
  464. laBaseNode* bn=memAcquire(NodeType->NodeSize);
  465. bn->Type=NodeType; NodeType->Init(bn); lstAppendItem(&ir->Nodes, bn); bn->InRack=ir;
  466. if(ir->RackType==LA_RACK_TYPE_INPUT){ laNotifyUsers("la.input_mapping"); laRecordAndPush(0,"la.input_mapping","Add node", 0); }
  467. else{ laNotifyUsers("la.drivers"); laRecordAndPush(0,"la.drivers","Add node", 0); }
  468. return bn;
  469. }
  470. void la_DestroyInputMapperNode(laBaseNode* bn){
  471. lstRemoveItem(bn->InRack, bn); bn->Type->Destroy(bn);
  472. laNotifyUsers("la.input_racks"); laRecordAndPush(0,"la.input_mapping","Delete node", 0);
  473. memFree(bn);
  474. }
  475. int OPINV_AddNode(laOperator* a, laEvent *e){
  476. laNodeRack* ir=a->This?a->This->EndInstance:0; if(!ir) return LA_CANCELED;
  477. laBaseNodeType* bnt=0;
  478. if(!MAIN.CurrentNodeCategory) MAIN.CurrentNodeCategory=MAIN.NodeCategories.pFirst;
  479. char* target=strGetArgumentString(a->ExtraInstructionsP,"target");
  480. if(!target || strSame(target,"INPUT")){ MAIN.FilterNodeCategory=LA_RACK_TYPE_INPUT;
  481. if(!(MAIN.CurrentNodeCategory->For&LA_RACK_TYPE_INPUT)) MAIN.CurrentNodeCategory=LA_NODE_CATEGORY_INPUT; }
  482. else{ MAIN.FilterNodeCategory=LA_RACK_TYPE_DRIVER;
  483. if(!(MAIN.CurrentNodeCategory->For&LA_RACK_TYPE_DRIVER)) MAIN.CurrentNodeCategory=LA_NODE_CATEGORY_DRIVER; }
  484. char* type=strGetArgumentString(a->ExtraInstructionsP,"type");
  485. 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; }
  486. else{
  487. for(int i=0;i<MAIN.NodeTypeNext;i++){
  488. if(strSame(MAIN.NodeTypes[i]->TypeName,type)){ la_CreateNode(ir, MAIN.NodeTypes[i]); }
  489. }
  490. }
  491. return LA_FINISHED;
  492. }
  493. int OPMOD_AddNode(laOperator* a, laEvent *e){
  494. laNodeRack* r=a->This->EndInstance;
  495. if(a->ConfirmData){
  496. if(a->ConfirmData->StrData){
  497. for(int i=0;i<MAIN.NodeTypeNext;i++){
  498. if(strSame(MAIN.NodeTypes[i]->TypeName,a->ConfirmData->StrData)){ la_CreateNode(r, MAIN.NodeTypes[i]); break; }
  499. }
  500. }
  501. return LA_FINISHED;
  502. }
  503. return LA_RUNNING;
  504. }
  505. void laui_AddNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  506. laColumn* c=laFirstColumn(uil),*cl,*cr; laSplitColumn(uil,c,0.4); cl=laLeftColumn(c,4); cr=laRightColumn(c,0);
  507. laShowItemFull(uil,cl,0,"la.node_categories",LA_WIDGET_COLLECTION,"feedback=NONE;",0,0);
  508. 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;
  509. laShowItemFull(gu,gc,0,"la.node_categories",LA_WIDGET_COLLECTION_SINGLE,0,laui_NodeCategory,0)->Flags|=LA_UI_FLAGS_NO_DECAL;
  510. }
  511. int OPINV_MoveNodeToRack(laOperator* a, laEvent *e){
  512. laBaseNode* n=a->This?a->This->EndInstance:0; if(!n||!n->InRack) return LA_CANCELED;
  513. laBaseNodeType* bnt=0; laNodeRack* target;
  514. char* direction=strGetArgumentString(a->ExtraInstructionsP,"direction");
  515. if(n->InRack->RackType==LA_RACK_TYPE_DRIVER){ laNotifyUsers("la.drivers"); }
  516. else{ laNotifyUsers("la.input_mapping"); }
  517. if(strSame(direction,"left")) target=n->InRack->Item.pPrev; else target=n->InRack->Item.pNext;
  518. if(!target) return LA_CANCELED;
  519. lstRemoveItem(&n->InRack->Nodes, n); lstAppendItem(&target->Nodes,n); n->InRack=target;
  520. return LA_FINISHED;
  521. }
  522. int OPINV_DeleteNode(laOperator* a, laEvent *e){
  523. laBaseNode* n=a->This?a->This->EndInstance:0; if(!n||!n->InRack) return LA_CANCELED;
  524. laBaseNodeType* bnt=0; laNodeRack* target;
  525. if(n->InRack->RackType==LA_RACK_TYPE_DRIVER){ laDriverRequestRebuild(); laNotifyUsers("la.drivers"); }
  526. else{ laMappingRequestRebuild(); laNotifyUsers("la.input_mapping"); }
  527. lstRemoveItem(&n->InRack->Nodes, n); n->Type->Destroy(n); memLeave(n);
  528. return LA_FINISHED;
  529. }
  530. int OPINV_MoveRack(laOperator* a, laEvent *e){
  531. laNodeRack* r=a->This?a->This->EndInstance:0; if(!r) return LA_CANCELED;
  532. char* direction=strGetArgumentString(a->ExtraInstructionsP,"direction");
  533. if(strSame(direction,"left")) lstMoveUp(&r->ParentPage->Racks,r); else lstMoveDown(&r->ParentPage->Racks,r);
  534. if(r->RackType==LA_RACK_TYPE_DRIVER){ laNotifyUsers("la.drivers"); laRecordAndPush(0,"la.drivers","Move rack", 0); }
  535. else{ laNotifyUsers("la.input_mapping"); laRecordAndPush(0,"la.input_mapping","Move rack", 0); }
  536. return LA_FINISHED;
  537. }
  538. int OPINV_InsertRack(laOperator* a, laEvent *e){
  539. laNodeRack* rr=a->This?a->This->EndInstance:0; if(!rr) return LA_CANCELED;
  540. laNodeRack* r=memAcquire(sizeof(laNodeRack));
  541. strSafeSet(&r->Name,"New Rack");
  542. lstInsertItemAfter(&rr->ParentPage->Racks,r,rr); r->ParentPage=rr->ParentPage; r->RackType=rr->RackType;
  543. if(r->RackType==LA_RACK_TYPE_DRIVER){ laNotifyUsers("la.drivers"); laRecordAndPush(0,"la.drivers","Insert rack", 0); }
  544. else{ laNotifyUsers("la.input_mapping"); laRecordAndPush(0,"la.input_mapping","Insert rack", 0); }
  545. return LA_FINISHED;
  546. }
  547. int OPINV_DeleteRack(laOperator* a, laEvent *e){
  548. laNodeRack* rr=a->This?a->This->EndInstance:0; if(!rr) return LA_CANCELED;
  549. if(strSame(strGetArgumentString(a->ExtraInstructionsP,"confirm"),"true")){
  550. laBaseNode* n; while(n=lstPopItem(&rr->Nodes)){ n->Type->Destroy(n); memLeave(n); }
  551. strSafeDestroy(&rr->Name); lstRemoveItem(&rr->ParentPage->Racks, rr); memLeave(rr);
  552. if(rr->RackType==LA_RACK_TYPE_DRIVER){ laNotifyUsers("la.drivers"); laRecordAndPush(0,"la.input_mapping","Delete rack", 0); }
  553. else{ laNotifyUsers("la.input_mapping"); laRecordAndPush(0,"la.input_mapping","Delete rack", 0); }
  554. return LA_FINISHED;
  555. }
  556. laEnableOperatorPanel(a,a->This,e->x,e->y,200,200,0,0,0,0,0,0,0,0,e);
  557. return LA_RUNNING;
  558. }
  559. void laui_DeleteRack(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  560. laColumn* c=laFirstColumn(uil);
  561. laShowItemFull(uil,c,This,"delete",0,"confirm=true;",0,0);
  562. }
  563. laPropContainer* laget_BaseNodeType(laBaseNode* bn){
  564. for(int i=0;i<MAIN.NodeTypeNext;i++){ if(bn->Type==MAIN.NodeTypes[i]) return MAIN.NodeTypes[i]->pc; }
  565. return LA_PC_IDN_GENERIC;
  566. }
  567. int laget_BaseNodeGap(laNodeRack* rack_unused, laBaseNode* n){
  568. return n->Gap;
  569. }
  570. void laset_BaseNodeGap(laBaseNode* n, int gap){
  571. laBaseNode* nn;
  572. if(gap==-1){
  573. int done=0; nn=n; while(nn){ if(nn->Gap>0){ nn->Gap--; done=1; break; } nn=nn->Item.pPrev; }
  574. if(done){ nn=n->Item.pNext; while(nn){ if(nn->Gap>0){ nn->Gap++; break; } nn=nn->Item.pNext; } }
  575. }elif(gap==1){
  576. n->Gap+=gap; nn=n->Item.pNext; while(nn){ if(nn->Gap>0){ nn->Gap--; break; } nn=nn->Item.pNext; }
  577. }elif(gap==-2){
  578. if(n->Gap){ n->Gap--; if(nn=n->Item.pNext){ nn->Gap++; } }
  579. elif(nn=n->Item.pPrev){ n->Gap=nn->Gap; nn->Gap=0; lstRemoveItem(&n->InRack->Nodes,n); lstInsertItemBefore(&n->InRack->Nodes,n,nn); }
  580. }elif(gap==2){
  581. 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++; } }
  582. else n->Gap++;
  583. }
  584. }
  585. void laset_InputNodeUserID(laInputControllerNode* n, int i){
  586. laNotifyUsers("la.input_racks");
  587. }
  588. void laset_InputControllerNodeSocketWhich(laInputControllerNodeSocket* s, char* str){
  589. strSafeSet(&s->Which, str);
  590. laNotifyUsers("la.input_racks"); laMappingRequestRebuild();
  591. }
  592. int laget_SocketEnumArrayLength(laInputControllerNodeSocket* s){
  593. return s->Out->ArrLen?s->Out->ArrLen:1;
  594. }
  595. int laget_VisualizerArrayLength(laInputVisualizerNode* s){
  596. return s->In->ArrLen?s->In->ArrLen:1;
  597. }
  598. laBoxedTheme* laget_NodeGetTheme(laNodeRack* rack_unused, laBaseNode* n){
  599. return 0;
  600. }
  601. void laRegisterNode(laBaseNodeType* type, laPropContainer* pc,
  602. laBaseNodeInitF init, laBaseNodeDestroyF destroy, laBaseNodeVisitF visit, laBaseNodeEvalF eval,
  603. int nodesize, char* udf_string, char* type_string, char* UiText, int icon){
  604. arrEnsureLength(&MAIN.NodeTypes, MAIN.NodeTypeNext, &MAIN.NodeTypeMax, sizeof(laBaseNode*));
  605. type->Init = init; type->Destroy = destroy; type->Visit=visit; type->Eval=eval; type->NodeSize=nodesize; type->pc=pc;
  606. type->TypeName=type_string;type->Name=UiText;type->Icon=icon;
  607. MAIN.NodeTypes[MAIN.NodeTypeNext]=type; MAIN.NodeTypeNext++;
  608. la_UDFAppendSharedTypePointer(udf_string, type);
  609. }
  610. void la_AddValuesNodeEnum(laProp* p){
  611. laAddEnumItemAs(p,"FLOAT","Float","Float value",LA_VALUES_NODE_FLOAT,0);
  612. laAddEnumItemAs(p,"INT","Int","Int value",LA_VALUES_NODE_INT,0);
  613. laAddEnumItemAs(p,"ENUM","Switch","Swich value",LA_VALUES_NODE_ENUM,0);
  614. }
  615. void la_AddValuesNodeEnumValue(laProp* p){
  616. laAddEnumItemAs(p,"IDLE","Idle","Idle",0,0);
  617. laAddEnumItemAs(p,"ACTIVE","Active","Active",1,0);
  618. }
  619. void la_RegisterInputMapperOperators(){
  620. laPropContainer *pc; laProp *p;
  621. laOperatorType *at;
  622. laEnumProp *ep;
  623. laCreateOperatorType("LA_add_input_mapping_page", "Add Page", "Add a page for inpur mapping", 0,0,0,OPINV_AddInputMapperPage,0,'+',0);
  624. laCreateOperatorType("LA_add_rack", "Add Rack", "Add a rack for nodes", 0,0,0,OPINV_AddNodesRack,0,'+',0);
  625. at=laCreateOperatorType("OPINV_AddNode", "Add Node", "Add a node to the rack",0,0,0,OPINV_AddNode,OPMOD_AddNode,'+',0);
  626. at->UiDefine=laui_AddNode;
  627. laCreateOperatorType("LA_input_mapping_rebuild", "Rebuild Input Mapping", "Rebuild input mapping for evaluation",0,0,0,OPINV_RebuildInputMapping,0,L'⭮',0);
  628. laCreateOperatorType("LA_move_node_to_rack", "Move Node", "Move node to another rack",0,0,0,OPINV_MoveNodeToRack,0,0,0);
  629. laCreateOperatorType("LA_delete_node", "Delete Node", "Delete this node",0,0,0,OPINV_DeleteNode,0,0,0);
  630. laCreateOperatorType("LA_move_rack", "Move Rack", "Move this rack",0,0,0,OPINV_MoveRack,0,0,0);
  631. laCreateOperatorType("LA_insert_rack", "Insert Rack", "Insert a new rack",0,0,0,OPINV_InsertRack,0,0,0);
  632. at=laCreateOperatorType("LA_delete_rack", "Delete Rack", "Delete a rack",0,0,0,OPINV_DeleteRack,OPMOD_FinishOnData,L'❌',0);
  633. at->UiDefine=laui_DeleteRack;
  634. pc=laAddPropertyContainer("la_node_rack", "Input Rack", "Input rack for putting input mapping nodes",0,0,sizeof(laNodeRack),0,0,1);
  635. laAddStringProperty(pc,"name","Name","Name of this rack",0,0,0,0,1,offsetof(laNodeRack,Name),0,0,0,0,LA_AS_IDENTIFIER);
  636. 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);
  637. laSubGroupExtraFunctions(p,0,laget_NodeGetTheme,laget_BaseNodeGap,0);
  638. 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);
  639. 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);
  640. laAddOperatorProperty(pc,"add_node","Add Node","Add a node into this rack","OPINV_AddNode",'+',0);
  641. laAddOperatorProperty(pc,"insert_rack","Insert Rack","Insert a rack","LA_insert_rack",'+',0);
  642. laAddOperatorProperty(pc,"move","Move Rack","Move this rack","LA_move_rack",0,0);
  643. laAddOperatorProperty(pc,"delete","Delete Rack","Delete this rack","LA_delete_rack",0,0);
  644. pc=laAddPropertyContainer("la_base_node", "Input Node", "Input logic node",0,0,sizeof(laBaseNode),0,0,1);
  645. LA_PC_IDN_GENERIC=pc;
  646. laAddStringProperty(pc,"name","Name","Name of this input node",0,0,0,0,1,offsetof(laBaseNode,Name),0,0,0,0,LA_AS_IDENTIFIER);
  647. 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);
  648. 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);
  649. laAddOperatorProperty(pc,"move","Move","Move node across racks","LA_move_node_to_rack",0,0);
  650. laAddOperatorProperty(pc,"delete","Delete","Delete node","LA_delete_node",0,0);
  651. 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);
  652. pc=laAddPropertyContainer("la_input_controller_node", "Controller output", "Output controller values",0,laui_ControllerNode,sizeof(laInputControllerNode),0,0,1);
  653. LA_PC_IDN_CONTROLLER=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  654. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  655. 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);
  656. 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);
  657. 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);
  658. 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);
  659. 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);
  660. 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);
  661. 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);
  662. 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);
  663. 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);
  664. 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);
  665. 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);
  666. 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);
  667. 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);
  668. 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);
  669. laAddEnumItemAs(p,"IDLE", "Idle", "Button is not pressed", 0, 0);
  670. laAddEnumItemAs(p,"ACTIVE", "Active", "Button is pressed", 1, 0);
  671. 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);
  672. pc=laAddPropertyContainer("la_input_visualizer_node", "Visualizer", "Visualizer node",0,laui_InputVisualizeNode,sizeof(laInputVisualizerNode),0,0,1);
  673. LA_PC_IDN_VISUALIZER=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  674. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  675. 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);
  676. 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);
  677. 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);
  678. 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);
  679. laAddEnumItemAs(p,"IDLE", "Idle", "Button is not pressed", 0, 0);
  680. laAddEnumItemAs(p,"ACTIVE", "Active", "Button is pressed", 1, 0);
  681. pc=laAddPropertyContainer("la_split_node", "Split", "Split node",0,laui_SplitNode,sizeof(laSplitNode),0,0,1);
  682. LA_PC_IDN_SPLIT=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  683. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  684. 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);
  685. 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);
  686. 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);
  687. 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);
  688. 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);
  689. 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);
  690. 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);
  691. 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);
  692. 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);
  693. 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);
  694. 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);
  695. 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);
  696. pc=laAddPropertyContainer("la_switch_node", "Switch", "Switch node",0,laui_SwitchNode,sizeof(laSwitchNode),0,0,1);
  697. LA_PC_IDN_SWITCH=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  698. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  699. 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);
  700. 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);
  701. 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);
  702. 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);
  703. 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);
  704. 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);
  705. 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);
  706. 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);
  707. 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);
  708. 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);
  709. 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);
  710. pc=laAddPropertyContainer("la_switch_node_in_socket", "Switch In", "Input of many values",0,0,sizeof(laSwitchNodeInSocket),0,0,1|LA_PROP_OTHER_ALLOC);
  711. 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);
  712. pc=laAddPropertyContainer("la_combine_node", "Combine", "Combine node",0,laui_CombineNode,sizeof(laCombineNode),0,0,1);
  713. LA_PC_IDN_COMBINE=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  714. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  715. 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);
  716. 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);
  717. 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);
  718. 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);
  719. 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);
  720. 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);
  721. 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);
  722. 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);
  723. 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);
  724. 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);
  725. 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);
  726. pc=laAddPropertyContainer("la_values_node", "Values", "Values node",0,laui_ValuesNode,sizeof(laValuesNode),0,0,1);
  727. LA_PC_IDN_VALUES=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  728. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  729. 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);
  730. 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);
  731. 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);
  732. 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);
  733. 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);
  734. 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);
  735. 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);
  736. 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);
  737. 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);
  738. 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);
  739. 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);
  740. 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);
  741. 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);
  742. 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);
  743. 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);
  744. 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);
  745. 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);
  746. 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);
  747. 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);
  748. 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);
  749. 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);
  750. 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);
  751. 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);
  752. 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);
  753. 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);
  754. 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);
  755. 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);
  756. 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);
  757. 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);
  758. 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);
  759. 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);
  760. 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);
  761. 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);
  762. 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);
  763. 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);
  764. 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);
  765. 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);
  766. 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);
  767. 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);
  768. 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);
  769. pc=laAddPropertyContainer("la_matrix_node", "Matrix", "Matrix node",0,laui_MatrixNode,sizeof(laMatrixNode),0,0,1);
  770. LA_PC_IDN_MATRIX=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  771. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  772. 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);
  773. 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);
  774. 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);
  775. p=laAddEnumProperty(pc,"operation", "Operation", "Operation", 0,0,0,0,0,offsetof(laMatrixNode,Operation),0,0,0,0,0,0,0,0,0,0);
  776. laAddEnumItemAs(p,"MUL", "Multiply", "L x R", LA_MATRIX_NODE_OP_MUL, 0);
  777. laAddEnumItemAs(p,"INV", "Invert", "Invert L or R", LA_MATRIX_NODE_OP_INV, 0);
  778. pc=laAddPropertyContainer("la_math_node", "Math", "Math node",0,laui_MathNode,sizeof(laMathNode),0,0,1);
  779. LA_PC_IDN_MATH=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  780. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  781. 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);
  782. 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);
  783. 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);
  784. 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);
  785. 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);
  786. 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);
  787. p=laAddEnumProperty(pc,"operation", "Operation", "Operation", 0,0,0,0,0,offsetof(laMathNode, Operation),0,0,0,0,0,0,0,0,0,0);
  788. laAddEnumItemAs(p,"ADD", "Add", "L + R", LA_MATH_NODE_OP_ADD, 0);
  789. laAddEnumItemAs(p,"SUB", "Subtract", "L - R", LA_MATH_NODE_OP_SUB, 0);
  790. laAddEnumItemAs(p,"MUL", "Multiply", "L x R", LA_MATH_NODE_OP_MUL, 0);
  791. laAddEnumItemAs(p,"DIV", "Divide", "L / R", LA_MATH_NODE_OP_DIV, 0);
  792. laAddEnumItemAs(p,"POW", "Power", "pow(L,R)", LA_MATH_NODE_OP_POW, 0);
  793. laAddEnumItemAs(p,"LOG", "Log", "log(L)base(R)", LA_MATH_NODE_OP_LOG, 0);
  794. laAddEnumItemAs(p,"SIN", "Sine", "sin(L)", LA_MATH_NODE_OP_SIN, 0);
  795. laAddEnumItemAs(p,"COS", "Cosine", "cos(L)", LA_MATH_NODE_OP_COS, 0);
  796. laAddEnumItemAs(p,"TAN", "Tangent", "tan(L)", LA_MATH_NODE_OP_TAN, 0);
  797. laAddEnumItemAs(p,"ASIN", "Arcsin", "asin(L)", LA_MATH_NODE_OP_ASIN, 0);
  798. laAddEnumItemAs(p,"ACOS", "Arccosine", "acos(L)", LA_MATH_NODE_OP_ACOS, 0);
  799. laAddEnumItemAs(p,"ATAN", "Arctangent", "atan(L)", LA_MATH_NODE_OP_ATAN, 0);
  800. laAddEnumItemAs(p,"ATAN2", "Atan2", "atan2(L,R) where L or R can be zero", LA_MATH_NODE_OP_ATAN2, 0);
  801. LA_IDN_REGISTER("Controller",L'🕹',LA_IDN_CONTROLLER,LA_PC_IDN_CONTROLLER, IDN_ControllerInit, IDN_ControllerDestroy, IDN_ControllerVisit, IDN_ControllerEval, laInputControllerNode);
  802. LA_IDN_REGISTER("Visualizer",L'🔍',LA_IDN_VISUALIZER,LA_PC_IDN_VISUALIZER, IDN_InputVisualizeInit, IDN_InputVisualizeDestroy, IDN_InputVisualizeVisit, IDN_InputVisualizerEval, laInputVisualizerNode);
  803. LA_IDN_REGISTER("Split",L'⚟',LA_IDN_SPLIT,LA_PC_IDN_SPLIT, IDN_SplitInit, IDN_SplitDestroy, IDN_SplitVisit, IDN_SplitEval, laSplitNode);
  804. LA_IDN_REGISTER("Switch",L'🚦',LA_IDN_SWITCH,LA_PC_IDN_SWITCH, IDN_SwitchInit, IDN_SwitchDestroy, IDN_SwitchVisit, IDN_SwitchEval, laSwitchNode);
  805. LA_IDN_REGISTER("Combine",L'⚞',LA_IDN_COMBINE,LA_PC_IDN_COMBINE, IDN_CombineInit, IDN_CombineDestroy, IDN_CombineVisit, IDN_CombineEval, laCombineNode);
  806. LA_IDN_REGISTER("Values",0,LA_IDN_VALUES,LA_PC_IDN_VALUES, IDN_ValuesInit, IDN_ValuesDestroy, IDN_ValuesVisit, IDN_ValuesEval, laValuesNode);
  807. LA_IDN_REGISTER("Matrix",0,LA_IDN_MATRIX,LA_PC_IDN_MATRIX, IDN_MatrixInit, IDN_MatrixDestroy, IDN_MatrixVisit, IDN_MatrixEval, laMatrixNode);
  808. LA_IDN_REGISTER("Math",0,LA_IDN_MATH,LA_PC_IDN_MATH, IDN_MathInit, IDN_MathDestroy, IDN_MathVisit, IDN_MathEval, laMathNode);
  809. LA_NODE_CATEGORY_INPUT=laAddNodeCategory("Input",0,LA_RACK_TYPE_INPUT);
  810. LA_NODE_CATEGORY_MATH=laAddNodeCategory("Math",0,LA_RACK_TYPE_ALL);
  811. LA_NODE_CATEGORY_ROUTE=laAddNodeCategory("Route",0,LA_RACK_TYPE_ALL);
  812. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_INPUT, &LA_IDN_CONTROLLER,0);
  813. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_MATH, &LA_IDN_MATRIX,&LA_IDN_MATH,0);
  814. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_ROUTE, &LA_IDN_SPLIT, &LA_IDN_SWITCH, &LA_IDN_COMBINE, &LA_IDN_VALUES, &LA_IDN_VISUALIZER,0);
  815. }
  816. void laMappingRequestRebuild(){ MAIN.InputMapping->NeedRebuild=1; }
  817. void laMappingRequestEval(){ MAIN.InputMapping->NeedEval=1; }
  818. int la_RunInputMapping(){
  819. MAIN.InputMapping->NeedEval = 0;
  820. for(laListItemPointer*lip=MAIN.InputMapping->Eval.pFirst;lip;lip=lip->pNext){
  821. laBaseNode* n=lip->p; n->Type->Eval(n);
  822. }
  823. return 1;
  824. }
  825. int la_RebuildInputMapping(){
  826. MAIN.InputMapping->NeedRebuild = 0;
  827. while(lstPopPointer(&MAIN.InputMapping->Eval));
  828. laListHandle pending={0}; laRackPage* rp=MAIN.InputMapping->CurrentPage; if(!rp)return LA_DAG_FLAG_PERM;
  829. for(laNodeRack* ir=rp->Racks.pFirst;ir;ir=ir->Item.pNext){
  830. for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ lstAppendPointer(&pending,bn); bn->Eval=0; }
  831. }
  832. laBaseNode*n;int result=LA_DAG_FLAG_PERM; laListItemPointer*NextLip;
  833. for(laListItemPointer*lip=pending.pFirst;lip;lip=NextLip){ n=lip->p; NextLip=lip->pNext;
  834. if(n->Eval&LA_DAG_FLAG_PERM) continue;
  835. result=n->Type->Visit(n,&MAIN.InputMapping->Eval); if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&pending)); break; }
  836. }
  837. if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&MAIN.InputMapping->Eval)); return LA_DAG_FLAG_ERR; }
  838. return LA_DAG_FLAG_PERM;
  839. }
  840. //==================================================================================================
  841. laNodeOutSocket* laCreateOutSocket(void* NodeParentOptional, char* label, int DataType){
  842. laNodeOutSocket* os=memAcquire(sizeof(laNodeOutSocket));
  843. strSafeSet(&os->Label, label); os->DataType = DataType; os->Parent=NodeParentOptional;
  844. return os;
  845. }
  846. laNodeInSocket* laCreateInSocket(char* label, int DataType){
  847. laNodeInSocket* is=memAcquire(sizeof(laNodeInSocket));
  848. strSafeSet(&is->Label, label); is->DataType = DataType;
  849. return is;
  850. }
  851. void laDestroyInSocket(laNodeInSocket* s){ strSafeDestroy(&s->Label); memLeave(s); }
  852. void laDestroyOutSocket(laNodeOutSocket* s){ strSafeDestroy(&s->Label); memLeave(s); }
  853. laNodeCategory* laAddNodeCategory(char* Name,laUiDefineFunc* Ui,int ForRackTypes){
  854. laNodeCategory* nc=memAcquire(sizeof(laNodeCategory));
  855. lstAppendItem(&MAIN.NodeCategories,nc);
  856. strSafeSet(&nc->Name, Name); nc->Ui=Ui; nc->For=ForRackTypes;
  857. return nc;
  858. }
  859. void laNodeCategoryAddNodeTypes(laNodeCategory* nc, ...){
  860. va_list list; va_start(list,nc);
  861. laBaseNodeType* nt;
  862. while(nt=va_arg(list,laBaseNodeType*)){
  863. lstAppendPointer(&nc->NodeTypes, nt);
  864. }
  865. va_end(list);
  866. }