*/}}
Browse Source

EvaluatedScene sync

YimingWu 1 year ago
parent
commit
52dcb975f5
2 changed files with 89 additions and 6 deletions
  1. 26 0
      la_tns.h
  2. 63 6
      la_tns_kernel.c

+ 26 - 0
la_tns.h

@@ -429,8 +429,24 @@ NEED_STRUCTURE(tnsBatch)
 #define TNS_EVAL_LAYER_OUTLINE (1<<2)
 #define TNS_EVAL_LAYER_SELECTION (1<<3)
 
+#define TNS_EvAL_MODE_INIT   (1<<0)
+#define TNS_EVAL_MODE_ALWAYS (1<<1)
+#define TNS_EvAL_MODE_DEINIT (1<<2)
+
 NEED_STRUCTURE(tnsEvaluatedInstance);
 typedef void (*tnsDrawEvaluatedInstanceF)(tnsEvaluatedInstance* ei, void* CustomData);
+
+STRUCTURE(tnsEvaluatedNode){
+    laListItem Item;
+    tnsMatrix44d Mat;
+    tnsObject* Target;
+    laListHandle Children;
+};
+STRUCTURE(tnsEvaluatedScene){
+    tnsEvaluatedNode* Root;
+    tnsEvaluatedNode* CurrentParent;
+    tnsEvaluatedNode* CurrentChild;
+};
 STRUCTURE(tnsEvaluatedInstance){
     tnsObject *Object;
     tnsMatrix44d Mat;
@@ -441,6 +457,7 @@ STRUCTURE(tnsEvaluatedInstance){
 };
 STRUCTURE(tnsEvaluateData){
     int Done;
+    int EvaluateMode;
     tnsObject *Active;
     int FillOutline;
     int FillSelectionID;
@@ -450,6 +467,7 @@ STRUCTURE(tnsEvaluateData){
     tnsEvaluatedInstance* Overlays; int NextOverlay, MaxOverlay;
     tnsEvaluatedInstance* Selections; int NextSelection, MaxSelection;
     tnsMatrix44d* MatArr; int NextMat, MaxMat;
+    tnsEvaluatedScene* Scene;
 };
 
 NEED_STRUCTURE(laRackPageCollection);
@@ -1101,6 +1119,14 @@ void tnsEvaluateObjectTree(tnsObject* from, tnsEvaluateData* UseED);
 void tnsAddEvaluatedInstance(tnsEvaluateData* ed, tnsObject* ob, tnsDrawEvaluatedInstanceF Draw, int Layer, 
     int IsActive, int MeshSelectionType, int InstanceSelectionID);
 void tnsDrawLayer(tnsEvaluateData* ed,int Layer,void* CustomData);
+
+void tnsEvaluateNewNode(tnsEvaluateData* ed, tnsObject* ob);
+int tnsEvaluateTryRelinkExistingNode(tnsEvaluateData* ed, tnsObject* ob);
+void tnsEvaluateFreeNode(tnsEvaluatedNode* en);
+void tnsEvaluateSyncNode(tnsEvaluateData* ed, tnsObject* ob);
+void tnsEnsureEvalueatedScene(tnsEvaluateData* ed, tnsObject* root);
+void tnsPrintEvaluatedNode(tnsEvaluatedNode* en,int level);
+
 void tnsDrawObjectTree(tnsObject* from, int Layers,void* CustomData);
 void tnsDrawObjectOrigins(tnsObject *from, tnsObject *active, int AllOrigins);
 void tnsDrawCursor(tnsObject* root);

+ 63 - 6
la_tns_kernel.c

@@ -3742,6 +3742,7 @@ void tnsEvaluateInstancerObject(tnsInstancer* o, tnsEvaluateData* ed){
     ed->OverrideID=origid; ed->FillOutline=origoutline;
 }
 void tnsEvaluateThisObject(tnsObject *o, tnsEvaluateData* ed){
+    if(ed->EvaluateMode){ tnsEvaluateSyncNode(ed,o); }
     if (!o->Show) return;
     switch (o->Type){
     case TNS_OBJECT_MESH: tnsEvaluateMeshObject(o, ed); break;
@@ -3789,9 +3790,57 @@ void tnsSetObjectTreeEvaluationArgs(tnsObject* from, tnsObject* Active, int Fill
     SETARG(Active); SETARG(FillOutline); SETARG(FillSelectionID);
     if(set) ed->Done=0;
 }
+void tnsEvaluateNewNode(tnsEvaluateData* ed, tnsObject* ob){
+    tnsEvaluatedScene* s=ed->Scene;
+    tnsEvaluatedNode* en=memAcquire(sizeof(tnsEvaluatedNode)); en->Target=ob;
+    tnsMultiply44d(en->Mat,ed->MatArr[ed->NextMat-1],ob->GlobalTransform);
+    if(s->CurrentChild) lstInsertItemBefore(&s->CurrentParent->Children,en,s->CurrentChild);
+    else lstAppendItem(&s->CurrentParent->Children,en);
+    s->CurrentChild = en;
+}
+int tnsEvaluateTryRelinkExistingNode(tnsEvaluateData* ed, tnsObject* ob){
+    tnsEvaluatedScene* s=ed->Scene;
+    if(!s->CurrentChild) return 0;
+    int done=0; for(tnsEvaluatedNode* en=s->CurrentChild->Item.pNext;en;en=en->Item.pNext){
+        if(ob==en->Target){ done=1; lstRemoveItem(&s->CurrentParent->Children,en);
+            lstInsertItemBefore(&s->CurrentParent->Children,en,s->CurrentChild); break; }
+    }
+    return done;
+}
+void tnsEvaluateFreeNode(tnsEvaluatedNode* en){
+    tnsEvaluatedNode* sen;
+    while(sen=lstPopItem(&en->Children)){ tnsEvaluateFreeNode(sen); }
+    memFree(sen);
+}
+void tnsEvaluateSyncNode(tnsEvaluateData* ed, tnsObject* ob){
+    tnsEvaluatedScene* s=ed->Scene;
+    if(ob && ((!s->CurrentChild) || (s->CurrentChild->Target!=ob))){
+        if(!tnsEvaluateTryRelinkExistingNode(ed,ob)) tnsEvaluateNewNode(ed,ob);
+    }
+    if((!ob) && s->CurrentChild){ tnsEvaluatedNode* en=s->CurrentChild->Item.pPrev;
+        if(en) while(en->Item.pNext){ tnsEvaluatedNode* den=en->Item.pNext;
+            lstRemoveItem(&s->CurrentParent->Children,den); tnsEvaluateFreeNode(den); }
+        s->CurrentChild=0;
+    }
+}
+void tnsEnsureEvalueatedScene(tnsEvaluateData* ed, tnsObject* root){
+    if(!ed->Scene) ed->Scene=memAcquire(sizeof(tnsEvaluatedScene));
+    if(!ed->Scene->Root) ed->Scene->Root=memAcquire(sizeof(tnsEvaluatedNode));
+    ed->Scene->CurrentChild=ed->Scene->Root;
+    ed->Scene->CurrentChild->Target=root; tnsLoadIdentity44d(ed->Scene->CurrentChild->Mat);
+}
+void tnsPrintEvaluatedNode(tnsEvaluatedNode* en,int level){
+    for(int i=0;i<level;i++){ printf("  "); }
+    printf("%s\n",en->Target->Name?en->Target->Name->Ptr:"?");
+    for(tnsEvaluatedNode* sen=en->Children.pFirst;sen;sen=sen->Item.pNext){
+        tnsPrintEvaluatedNode(sen,level+1);
+    }
+    if(level==0){printf("\n");}
+}
 void tnsEvaluateObjectTree(tnsObject* from, tnsEvaluateData* UseED){
     if(!from) return;
     tnsEvaluateData* ed=UseED?UseED:(from->InRoot?(&from->InRoot->Evaluated):(&from->Evaluated));
+    //ed->EvaluateMode=TNS_EVAL_MODE_ALWAYS;
     if(ed->Done) return;
     elif(!UseED){ ed->NextCommand=ed->NextOverlay=ed->NextSelection=ed->NextOutline=ed->NextMat=0;
         if(!ed->Commands) arrInitLength(&ed->Commands,16,&ed->MaxCommand,sizeof(tnsEvaluatedInstance));
@@ -3801,14 +3850,22 @@ void tnsEvaluateObjectTree(tnsObject* from, tnsEvaluateData* UseED){
         if(!ed->MatArr) arrInitLength(&ed->MatArr,8,&ed->MaxMat,sizeof(tnsMatrix44d));
         tnsLoadIdentity44d(ed->MatArr[0]); ed->NextMat=1;
     }
+    tnsEvaluatedNode* CP,*CC;
+    if(ed->EvaluateMode){ if(!UseED){ tnsEnsureEvalueatedScene(ed,from); }
+        CP=ed->Scene->CurrentParent; CC=ed->Scene->CurrentChild;
+    }
+
+    tnsEvaluateThisObject(from, ed);
+    
+    if(ed->EvaluateMode){ ed->Scene->CurrentParent=ed->Scene->CurrentChild; ed->Scene->CurrentChild=ed->Scene->CurrentParent->Children.pFirst; }
+
     for (laListItemPointer* lip=from->ChildObjects.pFirst;lip;lip=lip->pNext){
-        tnsObject *o=lip->p;
-        tnsEvaluateThisObject(o, ed);
-        if (o->ChildObjects.pFirst){
-            tnsEvaluateObjectTree(o,ed);
-        }
+        tnsObject *o=lip->p; if (o){ tnsEvaluateObjectTree(o,ed); }
+        if(ed->EvaluateMode){ ed->Scene->CurrentChild=ed->Scene->CurrentChild?ed->Scene->CurrentChild->Item.pNext:0; }
     }
-    if(!UseED)ed->Done=1;
+
+    if(ed->EvaluateMode){ tnsEvaluateSyncNode(ed, 0); ed->Scene->CurrentParent=CP; ed->Scene->CurrentChild=CC; }
+    if(!UseED){ ed->Done=1; /* tnsPrintEvaluatedNode(ed->Scene->Root,0); */  }
 }
 void tnsDrawLayer(tnsEvaluateData* ed,int Layer,void* CustomData){
     tnsEvaluatedInstance* ei; int next=0;