|
@@ -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;
|