|
@@ -23,9 +23,11 @@ extern struct _tnsMain *T;
|
|
|
|
|
|
laBaseNodeType TNS_IDN_TRANSFORM;
|
|
|
laBaseNodeType TNS_IDN_MAKE_TRANSFORM;
|
|
|
+laBaseNodeType TNS_IDN_ACTION_PLAYER;
|
|
|
|
|
|
laPropContainer* TNS_PC_IDN_TRANSFORM;
|
|
|
laPropContainer* TNS_PC_IDN_MAKE_TRANSFORM;
|
|
|
+laPropContainer* TNS_PC_IDN_ACTION_PLAYER;
|
|
|
|
|
|
void IDN_TransformInit(tnsTransformNode* n, int NoCreate){
|
|
|
if(NoCreate){return;}
|
|
@@ -141,6 +143,74 @@ void tnsui_MakeTransformNode(laUiList *uil, laPropPack *This, laPropPack *Extra,
|
|
|
laEndRow(uil,b);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+void IDN_ActionPlayerInit(tnsActionPlayerNode* n, int NoCreate){
|
|
|
+ if(NoCreate){ return; }
|
|
|
+ strSafeSet(&n->Base.Name,"Make Transform");
|
|
|
+ n->Next=laCreateOutSocket(n,"NEXT",0); n->Prev=laCreateInSocket("PREV",0);
|
|
|
+ n->Transport=laCreateInSocket("TRANSPORT",0); n->Detached=laCreateInSocket("DETACHED",0); n->Time=laCreateInSocket("TIME",0);
|
|
|
+}
|
|
|
+void IDN_ActionPlayerDestroy(tnsActionPlayerNode* n){
|
|
|
+ laDestroyInSocket(n->Prev); laDestroyOutSocket(n->Next); strSafeDestroy(&n->Base.Name);
|
|
|
+ laDestroyInSocket(n->Transport); laDestroyInSocket(n->Time); laDestroyInSocket(n->Detached);
|
|
|
+}
|
|
|
+int IDN_ActionPlayerVisit(tnsActionPlayerNode* n, laNodeVisitInfo* vi){
|
|
|
+ LA_GUARD_THIS_NODE(n,vi);
|
|
|
+ if(LA_SRC_AND_PARENT(n->Prev)){ laBaseNode*bn=n->Prev->Source->Parent; LA_VISIT_NODE(bn,vi); }
|
|
|
+ LA_ADD_THIS_NODE(n,vi);
|
|
|
+ return LA_DAG_FLAG_PERM;
|
|
|
+}
|
|
|
+int IDN_ActionPlayerEval(tnsActionPlayerNode* n){
|
|
|
+ if(!T->Runtime.CurrentEN || !n->Action){ return 1; } tnsEvaluatedNode* en=T->Runtime.CurrentEN;
|
|
|
+ int transport = n->iTransport; LA_GET_SRC_AS_VALUE(transport,n->Transport);
|
|
|
+ int detached = n->iDetached; LA_GET_SRC_AS_VALUE(detached,n->Detached);
|
|
|
+ real time = 0; int has_time=n->Time->Source?1:0; LA_GET_SRC_AS_VALUE(time,n->Time);
|
|
|
+ if(en->ActionRetarget){
|
|
|
+ laActionRetarget* ar=en->ActionRetarget;
|
|
|
+ en->ActionRetarget->DetachedInNode = detached;
|
|
|
+ if(!en->ActionRetarget->DetachedInNode){ ar=((tnsRootObject*)en->Target)->ActionRetarget; }
|
|
|
+ laRetargetedAction* ra=la_AnimationGetRetargetedAction(ar,n->Action); if(!ra){ return 1; }
|
|
|
+ ra->PlayStatus = transport; if(has_time){ ra->PlayHead = time; }
|
|
|
+ }else{
|
|
|
+ tnsRootObject* o=en->Target; if(o->Base.Type!=TNS_OBJECT_ROOT){ return 1; }
|
|
|
+ if(has_time){ n->Action->Offset=0; n->Action->PlayHead=time; }
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+void IDN_ActionPlayerCopy(tnsActionPlayerNode* new, tnsActionPlayerNode* old, int DoRematch){
|
|
|
+ if(DoRematch){ LA_IDN_NEW_LINK(Prev) return; }
|
|
|
+ old->Next->Duplicated=new->Next; new->Time=old->Time; new->Transport=old->Transport; new->Detached=old->Detached;
|
|
|
+ new->iDetached = old->iDetached; new->iTransport = old->iTransport;
|
|
|
+}
|
|
|
+void tnsui_ActionPlayerNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
|
|
|
+ laColumn* c=laFirstColumn(uil),*cl,*cr,*cll,*clr;
|
|
|
+ LA_BASE_NODE_HEADER(uil,c,This);
|
|
|
+ laSplitColumn(uil,c,0.6); cl=laLeftColumn(c,0); cr=laRightColumn(c,3);
|
|
|
+ laSplitColumn(uil,cl,0.4); cll=laLeftColumn(cl,3); clr=laRightColumn(cl,0);
|
|
|
+ tnsActionPlayerNode*n=This->EndInstance;
|
|
|
+ laUiItem* b2, *rui;
|
|
|
+
|
|
|
+ laShowNodeSocket(uil,cr,This,"prev",0)->Flags|=LA_UI_SOCKET_LABEL_W;
|
|
|
+ laShowNodeSocket(uil,cr,This,"next",0)->Flags|=LA_UI_SOCKET_LABEL_W;
|
|
|
+
|
|
|
+ laUiItem* b=laBeginRow(uil,cl,0,0);
|
|
|
+ laShowNodeSocket(uil,cl,This,"in_transport",0); b2=laOnConditionThat(uil,c,laNot(laPropExpression(This,"in_transport.source")));{
|
|
|
+ laShowItemFull(uil,cl,This,"transport",0,"text=Transport",0,0)->Expand=1;
|
|
|
+ }laElse(uil,b2);{
|
|
|
+ laShowLabel(uil,cl,"Transport",0,0)->Expand=1;
|
|
|
+ }laEndCondition(uil,b2);
|
|
|
+ laShowNodeSocket(uil,cl,This,"in_detached",0); b2=laOnConditionThat(uil,c,laNot(laPropExpression(This,"in_detached.source")));{
|
|
|
+ laShowItemFull(uil,cl,This,"detached",0,"text=Detached",0,0)->Expand=1;
|
|
|
+ }laElse(uil,b2);{
|
|
|
+ laShowLabel(uil,cl,"Detached",0,0)->Expand=1;
|
|
|
+ }laEndCondition(uil,b2);
|
|
|
+ laEndRow(uil,b);
|
|
|
+
|
|
|
+ laShowNodeSocket(uil,cll,This,"in_time",0)->Flags|=LA_UI_SOCKET_LABEL_E;
|
|
|
+ laShowItemFull(uil,clr,This,"action",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
int OPCHK_AddDriverPage(laPropPack *This, laStringSplitor *ss){
|
|
|
if (This && la_EnsureSubTarget(This->LastPs->p,0) == TNS_PC_OBJECT_GENERIC) return 1;
|
|
|
return 0;
|
|
@@ -192,6 +262,10 @@ int OPINV_RebuildDrivers(laOperator* a, laEvent *e){
|
|
|
tnsObject* tnsget_FirstObject(void* unused, void* unused2){
|
|
|
return T->World->AllObjects.pFirst;
|
|
|
}
|
|
|
+laAction* tnsget_FirstActionFromActionPlayer(tnsActionPlayerNode* apn, void* unused2){
|
|
|
+ if(!apn->Base.InRack || !apn->Base.InRack->ParentPage || !apn->Base.InRack->ParentPage->ParentObject) return 0;
|
|
|
+ tnsRootObject* ro = apn->Base.InRack->ParentPage->ParentObject; return ro->Actions.pFirst;
|
|
|
+}
|
|
|
|
|
|
void tns_RegisterNodes(){
|
|
|
laPropContainer *pc; laProp *p;
|
|
@@ -225,11 +299,28 @@ void tns_RegisterNodes(){
|
|
|
laAddFloatProperty(pc,"use_rot", "Rotation", "Use Rotation",0,"X,Y,Z",0,0,0,0.05,0,0,offsetof(tnsMakeTransformNode, UseRot),0,0,3,0,0,0,0,0,0,0,0);
|
|
|
laAddFloatProperty(pc,"use_sca", "Scale", "Use Scale",0,0,0,0,0,0.05,0,0,offsetof(tnsMakeTransformNode, UseSca),0,0,0,0,0,0,0,0,0,0,0);
|
|
|
laAddFloatProperty(pc,"use_angle", "Angle", "Use Angle",0,0,0,0,0,0.05,0,0,offsetof(tnsMakeTransformNode, UseAngle),0,0,0,0,0,0,0,0,0,0,0);
|
|
|
+
|
|
|
+ pc=laAddPropertyContainer("tns_action_player_node", "Action Player", "Action player node",0,tnsui_ActionPlayerNode,sizeof(tnsActionPlayerNode),lapost_Node,0,1);
|
|
|
+ TNS_PC_IDN_ACTION_PLAYER=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,"prev", "Previous","Previous node","la_in_socket",0,0,0,offsetof(tnsActionPlayerNode,Prev),0,0,0,0,0,0,0,LA_UDF_SINGLE);
|
|
|
+ laAddSubGroup(pc,"next", "Next","Next node","la_out_socket",0,0,0,offsetof(tnsActionPlayerNode,Next),0,0,0,0,0,0,0,LA_UDF_SINGLE);
|
|
|
+ laAddSubGroup(pc,"in_transport", "In Transport","Transport input","la_in_socket",0,0,0,offsetof(tnsActionPlayerNode,Transport),0,0,0,0,0,0,0,LA_UDF_SINGLE);
|
|
|
+ laAddSubGroup(pc,"in_time", "In Time","Time Input","la_in_socket",0,0,0,offsetof(tnsActionPlayerNode,Time),0,0,0,0,0,0,0,LA_UDF_SINGLE);
|
|
|
+ laAddSubGroup(pc,"in_detached", "In Detached","Detached input","la_in_socket",0,0,0,offsetof(tnsActionPlayerNode,Detached),0,0,0,0,0,0,0,LA_UDF_SINGLE);
|
|
|
+ ep=laAddEnumProperty(pc,"transport","Transport","Action in transport",LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(tnsActionPlayerNode,iTransport),0,0,0,0,0,0,0,0,0,0);
|
|
|
+ laAddEnumItemAs(ep,"STOPPED","Stopped","Player is stopped",0,0);
|
|
|
+ laAddEnumItemAs(ep,"PLAYING","Playing","Player is playing",1,0);
|
|
|
+ ep=laAddEnumProperty(pc,"detached","Detached","Action is detached on the instance",LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(tnsActionPlayerNode,iDetached),0,0,0,0,0,0,0,0,0,0);
|
|
|
+ laAddEnumItemAs(ep,"NONE","None","Action is reused from instancer",0,0);
|
|
|
+ laAddEnumItemAs(ep,"DETACHED","Detached","Action state is on instance itself",1,0);
|
|
|
+ laAddSubGroup(pc,"action","Action","Target action","la_animation_action",0,0,0,offsetof(tnsActionPlayerNode,Action),tnsget_FirstActionFromActionPlayer,0,laget_ListNext,0,0,0,0,LA_UDF_REFER);
|
|
|
|
|
|
LA_IDN_REGISTER("Transform",0,TNS_IDN_TRANSFORM,TNS_PC_IDN_TRANSFORM, IDN_Transform, tnsTransformNode);
|
|
|
LA_IDN_REGISTER("Make Transform",0,TNS_IDN_MAKE_TRANSFORM,TNS_PC_IDN_MAKE_TRANSFORM, IDN_MakeTransform, tnsMakeTransformNode);
|
|
|
+ LA_IDN_REGISTER("Action Player",0,TNS_IDN_ACTION_PLAYER,TNS_PC_IDN_ACTION_PLAYER, IDN_ActionPlayer, tnsActionPlayerNode);
|
|
|
|
|
|
laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_MATH, &TNS_IDN_MAKE_TRANSFORM,0);
|
|
|
- laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_DRIVER, &TNS_IDN_TRANSFORM,0);
|
|
|
+ laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_DRIVER, &TNS_IDN_TRANSFORM, &TNS_IDN_ACTION_PLAYER,0);
|
|
|
}
|
|
|
|