*/}}
Browse Source

More animation adaptations

YimingWu 7 months ago
parent
commit
c5fb5ecc37
5 changed files with 54 additions and 16 deletions
  1. 21 12
      la_animation.c
  2. 7 1
      la_data.h
  3. 8 0
      la_tns_kernel.c
  4. 1 1
      resources/la_operators.c
  5. 17 2
      resources/la_properties.c

+ 21 - 12
la_animation.c

@@ -67,12 +67,18 @@ void laAnimationUpdateHolderList(){
     }
     laNotifyUsers("la.animation.action_holders"); 
 }
+laActionHolder* laFindAnimationHolder(void* inst,char* container){
+    for(laActionHolder*ah=MAIN.Animation->ActionHolders.pFirst;ah;ah=ah->Item.pNext){
+        if(ah->Instance==inst){ if(ah->Container&&strSame(ah->Container->Identifier,container)) return ah; }
+    }
+    return 0;
+}
 
 laAction* laAnimiationNewAction(laActionHolder* ah, char* Name){
     laAction* aa=memAcquire(sizeof(laAction));
     if(!Name || !Name[0]){ Name="New Action"; }
     strSafeSet(&aa->Name,Name);
-    aa->Length=2; aa->FrameCount=24; memAssignRef(aa,&aa->Holder,ah);
+    aa->Length=2; aa->FrameCount=24; aa->HolderContainer=ah->Container;
     memAssignRef(aa,&aa->HolderInstance,ah->Instance);
     memAssignRef(MAIN.Animation,&MAIN.Animation->CurrentAction,aa);
     void* lh=((uint8_t*)ah->Instance)+ah->ActionOffset;
@@ -82,8 +88,9 @@ laAction* laAnimiationNewAction(laActionHolder* ah, char* Name){
     return aa;
 }
 laActionProp* laAnimationEnsureProp(laAction* aa, void* hyper1, laProp* p){
-    int DataSize=la_GetKeyablePropertyStorageSize(p); if(!DataSize || !aa->HolderInstance || !aa->Holder) return 0;
-    laListHandle *pl=((uint8_t*)aa->HolderInstance)+aa->Holder->PropOffset;
+    int DataSize=la_GetKeyablePropertyStorageSize(p); if(!DataSize || !aa->HolderInstance || !aa->HolderContainer) return 0;
+    laSubProp* paap=la_PropLookup(&aa->HolderContainer->Props,"__action_props__"); if(!paap){ return 0; }
+    laListHandle *pl=((uint8_t*)aa->HolderInstance)+paap->ListHandleOffset;
     for(laActionProp* ap=pl->pFirst;ap;ap=ap->Item.pNext){ if(ap->For==hyper1 && ap->Prop==p){ return ap; } }
     laActionProp* ap = memAcquire(sizeof(laActionProp)); lstAppendItem(pl,ap);
     memAssignRef(ap,&ap->For,hyper1); ap->Prop=p;
@@ -124,9 +131,9 @@ void laAnimationStoreKeyValue(laActionChannel* ac, laActionKey* ak){
 }
 laActionKey* laAnimationInsertKeyFrame(laAction* aa, void* hyper1, laProp* p, int* error){
     if(error) *error=0; if(!aa) return 0;
-    if(!aa->HolderInstance||!aa->Holder||!aa->Holder->Container){ if(error) *error=1; return 0; }
-    if(aa->Holder->Container->ActionHolderVerify){
-        if(!aa->Holder->Container->ActionHolderVerify(aa->HolderInstance,aa->Holder->Container,hyper1,p->Container)){
+    if(!aa->HolderInstance||!aa->HolderContainer){ if(error) *error=1; return 0; }
+    if(aa->HolderContainer->ActionHolderVerify){
+        if(!aa->HolderContainer->ActionHolderVerify(aa->HolderInstance,aa->HolderContainer,hyper1,p->Container)){
             if(error) *error=2; return 0;
         }
     }
@@ -212,8 +219,9 @@ void laAnimationRemoveAction(laAction* aa){
         if(aa->Item.pNext){ memAssignRef(MAIN.Animation,&MAIN.Animation->CurrentAction,aa->Item.pNext); }
         else{ memAssignRef(MAIN.Animation,&MAIN.Animation->CurrentAction,aa->Item.pPrev); }
     }
-    if(!aa->Holder || !aa->HolderInstance){ goto action_remove_clean; }
-    laListHandle* al=((uint8_t*)aa->HolderInstance)+aa->Holder->ActionOffset;
+    if(!aa->HolderContainer || !aa->HolderInstance){ goto action_remove_clean; }
+    laSubProp* paa=la_PropLookup(&aa->HolderContainer->Props,"__actions__"); if(!paa){ goto action_remove_clean; }
+    laListHandle* al=((uint8_t*)aa->HolderInstance)+paa->ListHandleOffset;
     lstRemoveItem(al,aa);
 action_remove_clean:
     memLeave(aa);
@@ -235,7 +243,7 @@ int OPMOD_AnimationRemoveAction(laOperator *a, laEvent *e){
 
     if(a->ConfirmData && a->ConfirmData->Mode==LA_CONFIRM_OK){
         laAnimationRemoveAction(aa); laNotifyUsers("la.animation");
-        laRecordInstanceDifferences(aa->HolderInstance,aa->Holder->Container->Identifier);
+        laRecordInstanceDifferences(aa->HolderInstance,aa->HolderContainer->Identifier);
         laRecordDifferences(0,"la.animation"); laPushDifferences("Remove action",0);
     }
 
@@ -449,11 +457,12 @@ void la_ActionMoveSelectedFrames(laAction* aa, int Delta){
     la_ActionEnsureFrameOrder(aa);
 }
 int la_ActionDeleteSelectedFrames(laAction* aa){
-    int any=0;
-    for(laActionChannel* ac=aa->Channels.pFirst;ac;ac=ac->Item.pNext){
+    int any=0; laActionChannel* NextAc;
+    for(laActionChannel* ac=aa->Channels.pFirst;ac;ac=NextAc){ NextAc=ac->Item.pNext;
         laActionKey* NextAk; for(laActionKey* ak=ac->Keys.pFirst;ak;ak=NextAk){ NextAk=ak->Item.pNext;if(!ak->Selected) continue;
-            lstRemoveItem(&ac->Keys, ak); memLeave(ak); any=1;
+            laAnimationRemoveFrame(ac,ak); any=1;
         }
+        if(!ac->Keys.pFirst){ laAnimationRemoveChannel(aa,ac); any=1; }
     }
     return any;
 }

+ 7 - 1
la_data.h

@@ -667,7 +667,7 @@ STRUCTURE(laAnimation){
 STRUCTURE(laAction){
     laListItem Item;
     laSafeString* Name;
-    void* HolderInstance; laActionHolder* Holder; // for verification
+    void* HolderInstance; laPropContainer* HolderContainer; // for verification
     laListHandle Channels;
     int FrameCount;
     real Length;
@@ -1038,6 +1038,10 @@ laActionChannel* laAnimationEnsureFrame(laActionChannel* ac, int frame);
 void laAnimationStoreKeyValue(laActionChannel* ac, laActionKey* ak);
 laActionKey* laAnimationInsertKeyFrame(laAction* aa, void* hyper1, laProp* p, int* error);
 
+void laAnimationRemoveFrame(laActionChannel* ac, laActionKey* ak);
+void laAnimationRemoveChannel(laAction* aa, laActionChannel* ac);
+void laAnimationRemoveAction(laAction* aa);
+
 void laAnimationSetPlayStatus(int PlayStatus);
 void laAnimationSetPlayHead(real time);
 
@@ -1045,3 +1049,5 @@ void la_AnimationPreFrame();
 void la_AnimationPostFrame();
 
 int laAnimationRegisterHolderPath(const char* Path);
+void laAnimationUpdateHolderList();
+

+ 8 - 0
la_tns_kernel.c

@@ -3484,6 +3484,8 @@ tnsObject *tnsCreateRootObject(char *name, int Use2D){
 
     o->Base.Drivers=memAcquire(sizeof(laRackPageCollection));
     o->Is2D=Use2D;
+    
+    laAnimationUpdateHolderList();
 
     return o;
 }
@@ -3505,11 +3507,17 @@ void tnsDestroyRootObject(tnsObject *root){
     }
     memLeave(root->Drivers); // root->Drivers=0; never reset address for single, see la_GiveDiffCommand()
 
+    tnsRootObject* ro=root; laAction* aa; laActionProp* ap;
+    while(aa=ro->Actions.pFirst){ laAnimationRemoveAction(aa); }
+    while(ap=lstPopItem(&ro->ActionProps)){ strSafeDestroy(&ap->CachedName); memLeave(ap); }
+
     lstRemoveItem(&w->RootObjects, root);
     tnsObject*co;
     while(co=lstPopPointerLeave(&root->ChildObjects)){ tnsDestroyObject(co); }
     strSafeDestroy(&root->Name);
     memLeave(root);
+
+    laAnimationUpdateHolderList();
 }
 void tnsDestroyObject(tnsObject *o){
     if(o->Type==TNS_OBJECT_ROOT){ tnsDestroyRootObject(o); return; }

+ 1 - 1
resources/la_operators.c

@@ -895,7 +895,7 @@ int OPINV_PropInsertKey(laOperator *a, laEvent *e){
         laEnableMessagePanel(a,0,"Error","Action holder info missing.\nThis should not happen.",e->x,e->y,100,e);
     }elif(err==2){
         char msg[1024]; char _id[128]="unknown container",*id=_id,_idc[128]="unknown object",*idc=_idc;
-        laTryGetInstanceIdentifier(aa->HolderInstance,aa->Holder->Container,_id,&id);
+        laTryGetInstanceIdentifier(aa->HolderInstance,aa->HolderContainer,_id,&id);
         laTryGetInstanceIdentifier(a->This->LastPs->UseInstance,a->This->LastPs->p->Container,_idc,&idc);
         sprintf(msg,"Can't insert key frame into current action.\n\"%s\" doesn't come from an action under \"%s\".",idc,id);
         laEnableMessagePanel(a,0,"Error",msg,e->x,e->y,100,e);

+ 17 - 2
resources/la_properties.c

@@ -809,6 +809,7 @@ int lafilter_NodeCategory(void* unused, laNodeCategory* c){
 
 void tnspost_World(tnsWorld *w){
     tnsRefreshMaterialLibraries();
+    laAnimationUpdateHolderList();
 }
 void tnspost_Material(tnsMaterial *m){
     tns_RefreshMaterial2D(m);
@@ -819,6 +820,13 @@ void tnspost_Object(tnsObject *o){ //XXX: No instance clear operation for object
     laListItemPointer* NextLip,*NextLip2;
     if(o->Type!=TNS_OBJECT_ROOT){
         tnsDeltaTransformValueChanged(o); tnsGlobalMatrixChanged(o,1);
+    }else{ tnsRootObject* ro=o;
+        for(laAction* aa=ro->Actions.pFirst;aa;aa=aa->Item.pNext){
+            if(!aa->HolderContainer){
+                aa->HolderContainer=la_ContainerLookup("tns_root_object");
+                aa->HolderInstance=ro;
+            }
+        }
     }
     for(laListItemPointer* lip=o->ChildObjects.pFirst;lip;lip=NextLip){
         NextLip=lip->pNext; if(!lip->p){ lstRemoveItem(&o->ChildObjects,lip); memFree(lip); continue; }
@@ -981,7 +989,7 @@ anim_set_prop_str_cleanup:
     strDestroyStringSplitor(&ss);
 }
 void* lagetraw_ActionKeyData(laActionKey* ak, int* r_size, int* ret_is_copy){
-    *r_size=ak->DataSize; *ret_is_copy=1;
+    *r_size=ak->DataSize; *ret_is_copy=1; if(!ak->DataSize){ return 0; }
     void* data=malloc(ak->DataSize); memcpy(data,ak->Data,ak->DataSize);
     return data;
 }
@@ -992,6 +1000,8 @@ void laset_AnimationPlayHead(void* unused,real data){
     if(data<0){ data=0; }
     laAnimationSetPlayHead(data); la_AnimationEvaluateActions(1); laNotifyUsers("la.animation");
 }
+void laget_ActionContainer(laAction* aa, char* str, char** here){ *here=aa->HolderContainer->Identifier; }
+void laread_ActionContainer(laAction* aa, char* str){ aa->HolderContainer=la_ContainerLookup(str); }
 
 int laaction_VerifyRootObject(void* Parent, laPropContainer* ParentType, void* Child, laPropContainer* ChildType){
     if(ParentType!=ChildType) return 0;
@@ -1931,7 +1941,7 @@ void la_RegisterInternalProps(){
 
 
         p = laAddPropertyContainer("la_animation", "Animation", "Animation data",0,0,sizeof(laAnimation),0,0,1);{
-            sp = laAddSubGroup(p, "action_holders", "Action Holders", "All action holders","la_animation_action_holder",0,0,0,-1,0,0,0,0,0,0,offsetof(laAnimation,ActionHolders),0);
+            sp = laAddSubGroup(p, "action_holders", "Action Holders", "All action holders","la_animation_action_holder",0,0,0,-1,0,0,0,0,0,0,offsetof(laAnimation,ActionHolders),LA_UDF_IGNORE);
             laSubGroupExtraFunctions(sp,0,0,0,0,laget_AnimationActionHolderCategory);
 
             laAddSubGroup(p, "current_action", "Current Action", "Current action","la_animation_action",0,0,0,offsetof(laAnimation,CurrentAction),0,0,0,0,0,0,0,LA_UDF_REFER|LA_READ_ONLY);
@@ -1944,6 +1954,9 @@ void la_RegisterInternalProps(){
         }
         p = laAddPropertyContainer("la_animation_action", "Action", "Animation action",0,0,sizeof(laAction),0,0,1);{
             laAddStringProperty(p,"name","Name","Name of the action",0,0,0,0,1,offsetof(laAction,Name),0,0,0,0,LA_AS_IDENTIFIER);
+            laAddStringProperty(p,"container","Container","Container of the action parent",0,0,0,0,0,0,0,laget_ActionContainer,0,laread_ActionContainer,LA_READ_ONLY);
+            laAddSubGroup(p, "holder", "Holder", "Holder data block", "any_pointer",0,0,0,offsetof(laAction, HolderInstance), 0,0,0,0,0,0,0,LA_UDF_REFER|LA_READ_ONLY);
+            laAddSubGroup(p, "holder_h2", "Holder H2", "Holder data block (hyper 2)", "any_pointer_h2",0,0,0,offsetof(laAction, HolderInstance), 0,0,0,0,0,0,0,LA_UDF_REFER|LA_READ_ONLY);
             laAddSubGroup(p, "channels", "Channels", "Action channels", "la_animation_channel",0,0,0,-1,0,0,0,0,0,0,offsetof(laAction, Channels),0);
             laAddFloatProperty(p, "length","Length","Length of the action in seconds",0,0,"s",30,0,0.1,2,0,offsetof(laAction,Length),0,0,0,0,0,0,0,0,0,0,0);
             laAddFloatProperty(p, "play_head","Play Head","Play Head position",0,0,0,1.0,0,0.01,0,0,offsetof(laAction,PlayHead),0,0,0,0,0,0,0,0,0,0,0);
@@ -1986,6 +1999,8 @@ void la_RegisterInternalProps(){
         }
         p = laAddPropertyContainer("la_animation_action_holder", "Action Holder", "Action holder",0,0,sizeof(laActionHolder),0,0,1);{
             laAddStringProperty(p,"name","Name","Name of the action",0,0,0,0,1,offsetof(laActionHolder,Name),0,0,0,0,LA_AS_IDENTIFIER);
+            laAddIntProperty(p,"action_offset","Action Offset","List handle offset of the action list in the instance",0,0,0,0,0,0,0,0,offsetof(laActionHolder,ActionOffset),0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY);
+            laAddIntProperty(p,"prop_offset","Prop Offset","List handle offset of the property list in the instance",0,0,0,0,0,0,0,0,offsetof(laActionHolder,PropOffset),0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY);
         }
     }