*/}}
Quellcode durchsuchen

New clamping and range sockets for random and mapper

YimingWu vor 2 Jahren
Ursprung
Commit
419c1b1b00
5 geänderte Dateien mit 59 neuen und 23 gelöschten Zeilen
  1. 4 3
      la_interface.h
  2. 1 1
      la_tns_kernel.c
  3. 45 14
      resources/la_nodes_basic.c
  4. 1 1
      resources/la_tns_drivers.c
  5. 8 4
      resources/la_widgets.c

+ 4 - 3
la_interface.h

@@ -1458,15 +1458,16 @@ STRUCTURE(laValueMapper){
 };
 STRUCTURE(laMapperNode){
     laBaseNode Base;
-    laNodeInSocket *In; /* *InMin,*InMax,*OutMin,*OutMax */
+    laNodeInSocket *In, *InMin, *InMax, *OutMin, *OutMax;
     laNodeOutSocket* Out;
     real rIn,rOut;
     laValueMapper* Mapper;
-    int Clamp;
+    int ClampInput, ClampOutput;
 };
 STRUCTURE(laRandomNode){
     laBaseNode Base;
     laNodeOutSocket* Out; real rOut;
+    laNodeInSocket *InMin, *InMax;
     real Min,Max;
 };
 STRUCTURE(laVectorMathNode){
@@ -1511,7 +1512,7 @@ STRUCTURE(laNodeCategory){
 
 laValueMapper* laValueMapperInit();
 laValueMapper* laValueMapperDestroy(laValueMapper* vm);
-real laValueMapperEvaluate(laValueMapper* vm, real x);
+real laValueMapperEvaluate(laValueMapper* vm, real x, real* force_InMin, real* force_InMax, real* force_OutMin, real* force_OutMax, int ClampIn, int ClampOut);
 
 void logPrintT(int Type, char* format, ...);
 void logPrint(char* format, ...);

+ 1 - 1
la_tns_kernel.c

@@ -180,7 +180,7 @@ void main(){\n\
         vec3 oNormal=fNormal; if(view<0){ oNormal=-fNormal; }\n\
         outNormal = oNormal;\n\
     }\n\
-    color=vec4(ConvertColorSpace(color.rgb),color.a);\n\
+    color=vec4(ConvertColorSpace(color.rgb),color.a); color.a=clamp(color.a,0,1);\n\
     outColor = color; \n\
     outGPos = fGPos;\n\
 }";

+ 45 - 14
resources/la_nodes_basic.c

@@ -510,27 +510,38 @@ void laui_SmallMathNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laCo
 void IDN_MapperInit(laMapperNode* n, int NoCreate){
     if(!NoCreate){
         strSafeSet(&n->Base.Name,"Mapper");
-        n->In=laCreateInSocket("IN",LA_PROP_FLOAT); n->Out=laCreateOutSocket(n,"OUT",LA_PROP_FLOAT);
         n->Mapper=laValueMapperInit();
     }
+    if(!n->In) n->In=laCreateInSocket("IN",LA_PROP_FLOAT); if(!n->Out) n->Out=laCreateOutSocket(n,"OUT",LA_PROP_FLOAT);
+    if(!n->InMin) n->InMin=laCreateInSocket("[IN",LA_PROP_FLOAT); if(!n->InMax) n->InMax=laCreateInSocket("IN]",LA_PROP_FLOAT);
+    if(!n->OutMin) n->OutMin=laCreateInSocket("[OUT",LA_PROP_FLOAT); if(!n->OutMax) n->OutMax=laCreateInSocket("OUT]",LA_PROP_FLOAT);
     n->Out->Data=&n->rOut;
 }
 void IDN_MapperDestroy(laMapperNode* n){
     strSafeDestroy(&n->Base.Name);
     laDestroyInSocket(n->In); laDestroyOutSocket(n->Out);
+    laDestroyInSocket(n->InMin); laDestroyInSocket(n->InMax); laDestroyInSocket(n->OutMin); laDestroyInSocket(n->OutMax);
     laValueMapperDestroy(n->Mapper);
 }
 int IDN_MapperVisit(laMapperNode* n, laListHandle* l){
     LA_GUARD_THIS_NODE(n);
     if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* bn=n->In->Source->Parent; LA_VISIT_NODE(bn); }
+    if(LA_SRC_AND_PARENT(n->InMin)){ laBaseNode* bn=n->InMin->Source->Parent; LA_VISIT_NODE(bn); }
+    if(LA_SRC_AND_PARENT(n->InMax)){ laBaseNode* bn=n->InMax->Source->Parent; LA_VISIT_NODE(bn); }
+    if(LA_SRC_AND_PARENT(n->OutMin)){ laBaseNode* bn=n->OutMin->Source->Parent; LA_VISIT_NODE(bn); }
+    if(LA_SRC_AND_PARENT(n->OutMax)){ laBaseNode* bn=n->OutMax->Source->Parent; LA_VISIT_NODE(bn); }
     n->Base.Eval=LA_DAG_FLAG_PERM;
     lstAppendPointer(l, n);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_MapperEval(laMapperNode* n){
-    real in=0;
+    real in=0; real* InMin=0,*InMax=0,*OutMin=0,*OutMax=0;
     if(LA_SRC_AND_PARENT(n->In) && (n->In->Source->DataType&LA_PROP_FLOAT)){ in=*((real*)n->In->Source->Data); }
-    real result=laValueMapperEvaluate(n->Mapper,in);
+    if(LA_SRC_AND_PARENT(n->InMin) && (n->InMin->Source->DataType&LA_PROP_FLOAT)){ InMin=n->InMin->Source->Data; }
+    if(LA_SRC_AND_PARENT(n->InMax) && (n->InMax->Source->DataType&LA_PROP_FLOAT)){ InMax=n->InMax->Source->Data; }
+    if(LA_SRC_AND_PARENT(n->OutMin) && (n->OutMin->Source->DataType&LA_PROP_FLOAT)){ OutMin=n->OutMin->Source->Data; }
+    if(LA_SRC_AND_PARENT(n->OutMax) && (n->OutMax->Source->DataType&LA_PROP_FLOAT)){ OutMax=n->OutMax->Source->Data; }
+    real result=laValueMapperEvaluate(n->Mapper,in,InMin,InMax,OutMin,OutMax,n->ClampInput,n->ClampOutput);
     n->rOut=result;
     return 1;
 }
@@ -541,13 +552,15 @@ void laui_MapperNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColum
     LA_BASE_NODE_HEADER(uil,c,This);
 
     b=laBeginRow(uil,c,0,0);
-    laShowNodeSocket(uil,c,This,"in",0)->Flags|=LA_UI_SOCKET_LABEL_E; laShowItem(uil,c,This,"mapper.in_range")->Expand=1;
+    laShowNodeSocket(uil,c,This,"in",0)->Flags|=LA_UI_SOCKET_LABEL_E; laShowItemFull(uil,c,This,"clamp_input",0,"text=C",0,0); laShowNodeSocket(uil,c,This,"in_min",0); 
+    laShowItem(uil,c,This,"mapper.in_range")->Expand=1; laShowNodeSocket(uil,c,This,"in_max",0); 
     laEndRow(uil,b);
 
     laShowItem(uil,c,This,"mapper");
 
     b=laBeginRow(uil,c,0,0);
-    laShowItem(uil,c,This,"mapper.out_range")->Expand=1;laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
+    laShowNodeSocket(uil,c,This,"out_min",0); laShowItem(uil,c,This,"mapper.out_range")->Expand=1;
+    laShowNodeSocket(uil,c,This,"out_max",0); laShowItemFull(uil,c,This,"clamp_output",0,"text=C",0,0); laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
     laEndRow(uil,b);
 }
 
@@ -555,17 +568,24 @@ void IDN_RandomInit(laRandomNode* n, int NoCreate){
     if(!NoCreate){
         strSafeSet(&n->Base.Name,"Random"); n->Out=laCreateOutSocket(n,"RAND",LA_PROP_FLOAT); n->Min=0; n->Max=1;
     }
+    if(!n->InMin) n->InMin=laCreateInSocket("[IN",LA_PROP_FLOAT); if(!n->InMax) n->InMax=laCreateInSocket("IN]",LA_PROP_FLOAT);
     n->Out->Data=&n->rOut;
 }
 void IDN_RandomDestroy(laRandomNode* n){
-    strSafeDestroy(&n->Base.Name); laDestroyOutSocket(n->Out);
+    strSafeDestroy(&n->Base.Name); laDestroyOutSocket(n->Out); laDestroyInSocket(n->InMin); laDestroyInSocket(n->InMax);
 }
 int IDN_RandomVisit(laRandomNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n); n->Base.Eval=LA_DAG_FLAG_PERM; lstAppendPointer(l, n);
+    LA_GUARD_THIS_NODE(n);
+    if(LA_SRC_AND_PARENT(n->InMin)){ laBaseNode* bn=n->InMin->Source->Parent; LA_VISIT_NODE(bn); }
+    if(LA_SRC_AND_PARENT(n->InMax)){ laBaseNode* bn=n->InMax->Source->Parent; LA_VISIT_NODE(bn); }
+    n->Base.Eval=LA_DAG_FLAG_PERM; lstAppendPointer(l, n);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_RandomEval(laRandomNode* n){
-    n->rOut=n->Min+(real)rand()/(real)(RAND_MAX/(n->Max-n->Min));
+    real Min=n->Min,Max=n->Max;
+    if(LA_SRC_AND_PARENT(n->InMin) && (n->InMin->Source->DataType&LA_PROP_FLOAT)){ Min=*((real*)n->InMin->Source->Data); }
+    if(LA_SRC_AND_PARENT(n->InMax) && (n->InMax->Source->DataType&LA_PROP_FLOAT)){ Max=*((real*)n->InMax->Source->Data); }
+    n->rOut=Min+(real)rand()/(real)(RAND_MAX/(Max-Min));
     return 1;
 }
 void laui_RandomNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
@@ -575,7 +595,8 @@ void laui_RandomNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColum
     LA_BASE_NODE_HEADER(uil,c,This);
 
     b=laBeginRow(uil,c,0,0);
-    laShowItem(uil,c,This,"range")->Expand=1;laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
+    laShowNodeSocket(uil,c,This,"min",0);  laShowItem(uil,c,This,"range")->Expand=1; laShowNodeSocket(uil,c,This,"max",0); 
+    laShowNodeSocket(uil,c,This,"out",0)->Flags|=LA_UI_SOCKET_LABEL_W;
     laEndRow(uil,b);
 }
 
@@ -884,6 +905,9 @@ laPropContainer* laget_BaseNodeType(laBaseNode* bn){
 int laget_BaseNodeGap(laNodeRack* rack_unused, laBaseNode* n){
     return n->Gap;
 }
+void laread_BaseNodeGap(laBaseNode* n, int gap){
+    n->Gap=gap;
+}
 void laset_BaseNodeGap(laBaseNode* n, int gap){
     laBaseNode* nn;
     if(gap==-1){
@@ -966,7 +990,7 @@ void la_RegisterInputMapperOperators(){
     pc=laAddPropertyContainer("la_base_node", "Input Node", "Input logic node",0,0,sizeof(laBaseNode),0,0,1);
     LA_PC_IDN_GENERIC=pc;
     laAddStringProperty(pc,"name","Name","Name of this input node",0,0,0,0,1,offsetof(laBaseNode,Name),0,0,0,0,LA_AS_IDENTIFIER);
-    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);
+    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,laread_BaseNodeGap,0,0);
     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);
     laAddOperatorProperty(pc,"move","Move","Move node across racks","LA_move_node_to_rack",0,0);
     laAddOperatorProperty(pc,"delete","Delete","Delete node","LA_delete_node",0,0);
@@ -1139,16 +1163,23 @@ void la_RegisterInputMapperOperators(){
     LA_PC_IDN_MAPPER=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
     laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
     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);
+    laAddSubGroup(pc,"in_min", "In Min","Minimum input value","la_in_socket",0,0,0,offsetof(laMapperNode, InMin),0,0,0,0,0,0,0,LA_UDF_SINGLE);
+    laAddSubGroup(pc,"in_max", "In Max","Maximum input value","la_in_socket",0,0,0,offsetof(laMapperNode, InMax),0,0,0,0,0,0,0,LA_UDF_SINGLE);
+    laAddSubGroup(pc,"out_min", "Out Min","Minimum output value","la_in_socket",0,0,0,offsetof(laMapperNode, OutMin),0,0,0,0,0,0,0,LA_UDF_SINGLE);
+    laAddSubGroup(pc,"out_max", "Out Max","Maximum output value","la_in_socket",0,0,0,offsetof(laMapperNode, OutMax),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     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);
     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);
-    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);
-    laAddEnumItemAs(p,"NONE", "None", "Don't clamp output", 0, 0);
-    laAddEnumItemAs(p,"CLAMP", "Clamp", "Clamp output to specified range", 1, 0);
+    p=laAddEnumProperty(pc,"clamp_input", "Clamp Input", "Clamp input", LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(laMapperNode,ClampInput),0,0,0,0,0,0,0,0,0,0);
+    laAddEnumItemAs(p,"NONE", "None", "Don't clamp", 0, 0); laAddEnumItemAs(p,"CLAMP", "Clamp", "Clamp to specified range", 1, 0);
+    p=laAddEnumProperty(pc,"clamp_output", "Clamp Output", "Clamp output", LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(laMapperNode,ClampOutput),0,0,0,0,0,0,0,0,0,0);
+    laAddEnumItemAs(p,"NONE", "None", "Don't clamp", 0, 0); laAddEnumItemAs(p,"CLAMP", "Clamp", "Clamp to specified range", 1, 0);
 
     pc=laAddPropertyContainer("la_random_node", "Random", "Random node",0,laui_RandomNode,sizeof(laRandomNode),0,0,1);
     LA_PC_IDN_RANDOM=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
     laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
     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);
+    laAddSubGroup(pc,"min", "Min","Minimum output value","la_in_socket",0,0,0,offsetof(laRandomNode, InMin),0,0,0,0,0,0,0,LA_UDF_SINGLE);
+    laAddSubGroup(pc,"max", "Max","Maximum output value","la_in_socket",0,0,0,offsetof(laRandomNode, InMax),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     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);
 
     pc=laAddPropertyContainer("la_vector_math_node", "Vector Math", "Math node",0,laui_VectorMathNode,sizeof(laVectorMathNode),0,0,1);
@@ -1240,7 +1271,7 @@ int la_RebuildInputMapping(){
     while(lstPopPointer(&MAIN.InputMapping->Eval));
     laListHandle pending={0}; laRackPage* rp=MAIN.InputMapping->CurrentPage; if(!rp)return LA_DAG_FLAG_PERM;
     for(laNodeRack* ir=rp->Racks.pFirst;ir;ir=ir->Item.pNext){
-        for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ lstAppendPointer(&pending,bn); bn->Eval=0; }
+        for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ if(!bn->InitDone){ bn->Type->Init(bn,1); bn->InitDone=1; } lstAppendPointer(&pending,bn); bn->Eval=0; }
     }
     laBaseNode*n;int result=LA_DAG_FLAG_PERM; laListItemPointer*NextLip;
     for(laListItemPointer*lip=pending.pFirst;lip;lip=NextLip){ n=lip->p; NextLip=lip->pNext;

+ 1 - 1
resources/la_tns_drivers.c

@@ -183,7 +183,7 @@ int la_RebuildDriverEval(){
     laListHandle pending={0};
     for(laRackPage* dp=MAIN.Drivers->Pages.pFirst;dp;dp=dp->Item.pNext){
         for(laNodeRack* ir=dp->Racks.pFirst;ir;ir=ir->Item.pNext){
-            for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ lstAppendPointer(&pending,bn); bn->Eval=0; }
+            for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ if(!bn->InitDone){ bn->Type->Init(bn,1); bn->InitDone=1; } lstAppendPointer(&pending,bn); bn->Eval=0; }
         }
     }
     laBaseNode*n;int result=LA_DAG_FLAG_PERM; laListItemPointer*NextLip;

+ 8 - 4
resources/la_widgets.c

@@ -2848,9 +2848,11 @@ laValueMapper* laValueMapperDestroy(laValueMapper* vm){
     while(vmp=lstPopItem(&vm->Points)){ memLeave(vmp); }
     memLeave(vm);
 }
-real laValueMapperEvaluate(laValueMapper* vm, real x){
-    if(fabs(vm->InRange[1]-vm->InRange[0])<1e-7) return 0;
-    x=tnsGetRatiod(vm->InRange[0],vm->InRange[1],x);
+real laValueMapperEvaluate(laValueMapper* vm, real x, real* force_InMin, real* force_InMax, real* force_OutMin, real* force_OutMax, int ClampIn, int ClampOut){
+    real InMin=vm->InRange[0], InMax=vm->InRange[1], OutMin=vm->OutRange[0], OutMax=vm->OutRange[1];
+    if(force_InMin) InMin=*force_InMin; if(force_InMax) InMax=*force_InMax; if(force_OutMin) OutMin=*force_OutMin; if(force_OutMax) OutMax=*force_OutMax;
+    if(fabs(InMax-InMin)<1e-7) return 0;
+    x=tnsGetRatiod(InMin,InMax,x); if(ClampIn) TNS_CLAMP(x,0,1);
     laValueMapperPoint* vmp,*NextVMP;
     real ey=0;
     for(vmp=vm->Points.pFirst;vmp;vmp=vmp->Item.pNext){
@@ -2861,7 +2863,9 @@ real laValueMapperEvaluate(laValueMapper* vm, real x){
         real ratio=tnsGetRatiod(vmp->x,NextVMP->x,x);
         ey=tnsInterpolate(vmp->y,NextVMP->y,ratio); break;
     }
-    return tnsInterpolate(vm->OutRange[0],vm->OutRange[1],ey);
+    real Out=tnsInterpolate(OutMin,OutMax,ey);
+    if(ClampOut) TNS_CLAMP(Out,OutMin,OutMax);
+    return Out;
 }
 int OPMOD_ValueMapper(laOperator *a, laEvent *e){
     laUiItem *ui = a->Instance;