*/}}
Browse Source

Instance selector basics working

YimingWu 1 year ago
parent
commit
f65b222c7f
8 changed files with 120 additions and 113 deletions
  1. 13 8
      la_kernel.c
  2. 1 1
      la_tns.h
  3. 24 23
      la_tns_kernel.c
  4. 2 2
      la_tns_mesh.c
  5. 5 3
      resources/la_modelling.c
  6. 11 27
      resources/la_properties.c
  7. 63 48
      resources/la_templates.c
  8. 1 1
      resources/la_tns_drivers.c

+ 13 - 8
la_kernel.c

@@ -3760,25 +3760,30 @@ laUiItem *laShowCanvas(laUiList *uil, laColumn *c, laPropPack *Base, const char
 }
 laUiItem *laShow3DCanvasCombo(laUiList *uil, laColumn *c, laPropPack *Base, const char *Path, int Height, laPropPack* Detached){
     laUiItem* ui=0;
+#define ADD_CANVAS \
+    laUiItem* b3=laOnConditionThat(uil,c,laPropExpression(&rb->PP,"active"));{\
+        laUiItem* b=laBeginRow(uil,cr,0,0);\
+        laShowLabel(uil,cr,"⯈",0,0); laShowItem(uil,cr,&rb->PP,"active.name")->Flags|=LA_UI_FLAGS_NO_DECAL;\
+        laEndRow(uil,b);\
+    }laEndCondition(uil,b3);
     if(Detached){
         laColumn* cl,*cll,*clr,*cr;
         laSplitColumn(uil,c,0.35); cl=laLeftColumn(c,7); cr=laRightColumn(c,0);
         laSplitColumn(uil,cl,0.4); cll=laLeftColumn(cl,1); clr=laRightColumn(cl,0);
         laShowItemFull(uil,cll,Detached,"detached",0,0,0,0)->Flags|=LA_UI_FLAGS_HIGHLIGHT|LA_UI_FLAGS_ICON;
-        laUiItem* rb=laShowItemFull(uil,clr,Detached,"root_object",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
-        laUiItem* b2=laOnConditionThat(uil,c,laPropExpression(&rb->PP,"active"));{
-            laUiItem* b=laBeginRow(uil,cr,0,0);
-            laShowLabel(uil,cr,"⯈",0,0); laShowItem(uil,cr,&rb->PP,"active.name")->Flags|=LA_UI_FLAGS_NO_DECAL;
-            laEndRow(uil,b);
-        }laEndCondition(uil,b2);
-        b2=laOnConditionThat(uil,c,laPropExpression(Detached,"detached"));{
+        laUiItem* b2=laOnConditionThat(uil,c,laPropExpression(Detached,"detached"));{
+            laUiItem* rb=laShowItemFull(uil,clr,Detached,"root_object",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
+            ADD_CANVAS
             ui=laShowCanvas(uil,c,Detached,"root_object",0,Height); laDefault3DViewOverlay(ui);
         }laElse(uil,b2);{
-            ui=laShowCanvas(uil,c,0,"tns.world.root_objects",0,Height); laDefault3DViewOverlay(ui);
+            laUiItem* rb=laShowItemFull(uil,clr,0,"tns.world.active_root",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
+            ADD_CANVAS
+            ui=laShowCanvas(uil,c,0,"tns.world.active_root",0,Height); laDefault3DViewOverlay(ui);
         }laEndCondition(uil,b2);
     }else{
         ui=laShowCanvas(uil,c,Base,Path,0,Height); laDefault3DViewOverlay(ui);
     }
+#undef ADD_CANVAS
 }
 laUiItem *laShowColumnAdjuster(laUiList *uil, laColumn *c){
     laUiItem *ui = memAcquireSimple(sizeof(laUiItem));

+ 1 - 1
la_tns.h

@@ -263,7 +263,7 @@ struct _tnsMain {
     tnsCommand* DrawingCommand;
     int NextCommand, MaxCommand;
 
-    tnsWorld World;
+    tnsWorld* World;
 
     laListHandle RenderBuffers;
     tnsRenderBuffer *ActiveRenderBuffer;

+ 24 - 23
la_tns_kernel.c

@@ -1247,6 +1247,7 @@ void tnsSetRayShaderUniformTextures(tnsOffscreen* doff){
 void tnsInitRenderKernel(int matrixStackLevel){
     tnsCommand *c;
     T = memAcquireHyper(sizeof(tnsMain));
+    T->World=memAcquire(sizeof(tnsWorld));
     GLuint m_nQuadVAO;
 
     T->GLVersionStr = glGetString(GL_VERSION);
@@ -1346,8 +1347,8 @@ void tnsQuit(){
     tnsQuitFontManager();
 
     tnsObject*o; 
-    while(o=lstPopItem(&T->World.AllObjects)){ tnsDestroyObject(o); }
-    while(o=lstPopItem(&T->World.RootObjects)){ tnsDestroyRootObject(o); }
+    while(o=lstPopItem(&T->World->AllObjects)){ tnsDestroyObject(o); }
+    while(o=lstPopItem(&T->World->RootObjects)){ tnsDestroyRootObject(o); }
     //memFreeRemainingLeftNodes();
 
     tnsDeleteBuiltinShaders();
@@ -1372,6 +1373,7 @@ void tnsQuit(){
     glDeleteVertexArrays(1,&T->GlobalVAO);
 
     FreeMem(T->stack.level);
+    memFree(T->World);
     memFree(T);
 }
 
@@ -3086,9 +3088,9 @@ void tnsDrawIcon(uint32_t ID, real Color[4], int L,int R, int T, int Flags){
 
 tnsObject *tnsFindObject(char *Name, tnsObject *FromObj){
     tnsObject *io; tnsObject *ro;
-    laListHandle* l=FromObj?(&FromObj->ChildObjects):(&T->World.AllObjects);
+    laListHandle* l=FromObj?(&FromObj->ChildObjects):(&T->World->AllObjects);
     for (laListItemPointer*lip=l->pFirst;lip;lip=lip->pNext){
-        io=((l==&T->World.AllObjects)?lip:lip->p); if (strSame(io->Name->Ptr, Name)){ return io; }
+        io=((l==&T->World->AllObjects)?lip:lip->p); if (strSame(io->Name->Ptr, Name)){ return io; }
         if (ro = tnsFindObject(Name, io)) return ro;
     }
     return 0;
@@ -3222,9 +3224,7 @@ void tnsGlobalTransformValueChanged(tnsObject* o){
 
 void tnsSetCurrentRoot(tnsObject *o){
     if(o->Type!=TNS_OBJECT_ROOT) return;
-    T->World.ActiveRoot=o;
-    // memAssignRef(s, &s->CurrentObject, o); we can't use this apparently because World is not Hyper 2.
-    // XXX: Needs fake mempool/user, or T->World prop redesign because T is runtime allocated.
+    memAssignRef(T->World, &T->World->ActiveRoot, o);
 }
 void tnsInitObjectBase(tnsObject *o, tnsObject *under, char *Name, int Type,
                         real AtX, real AtY, real AtZ,
@@ -3246,7 +3246,7 @@ void tnsInitObjectBase(tnsObject *o, tnsObject *under, char *Name, int Type,
     o->DrawMode = GL_LINE_LOOP;
     tnsLoadIdentity44d(o->DeltaTransform);
     tnsSelfTransformValueChanged(o);
-    lstAppendItem(&T->World.AllObjects, o);
+    lstAppendItem(&T->World->AllObjects, o);
     if (under){ lstAppendPointer(&under->ChildObjects, o);
         tnsObject* root=under->Type==TNS_OBJECT_ROOT?under:under->InRoot; memAssignRef(o, &o->InRoot, root); 
     }
@@ -3448,7 +3448,7 @@ void tnsTranslateViewingCamera(tnsCamera *c, int ViewportW, int ViewportH, real
 }
 
 tnsObject *tnsCreateRootObject(char *name){
-    tnsWorld *w = &T->World;
+    tnsWorld *w = T->World;
     tnsObject *o = memAcquireHyper(sizeof(tnsObject));
 
     o->Type==TNS_OBJECT_ROOT;
@@ -3462,7 +3462,7 @@ tnsObject *tnsCreateRootObject(char *name){
     return o;
 }
 void tnsDestroyRootObject(tnsObject *root){
-    tnsWorld *w = &T->World;
+    tnsWorld *w = T->World;
     tnsObject *o, *NextO;
     w->ActiveRoot = root->Item.pPrev ? root->Item.pPrev : root->Item.pNext ? root->Item.pNext : 0;
 
@@ -3484,7 +3484,7 @@ void tnsDestroyObject(tnsObject *o){
     tnsUnparentObject(o,1);
     while(o->ChildObjects.pFirst){ tnsUnparentObject(((laListItemPointer*)o->ChildObjects.pFirst)->p, 1); }
 
-    lstRemoveItem(&T->World.AllObjects, o);
+    lstRemoveItem(&T->World->AllObjects, o);
 
     if(o->InRoot){ lstRemovePointerLeave(&o->InRoot->ChildObjects, o);
         tnsInvalidateEvaluation(o);
@@ -3505,7 +3505,7 @@ tnsCamera *tnsCreateCamera(tnsObject *under, char *Name, real FOV,
                         real AtX, real AtY, real AtZ,
                         real RotX, real RotY, real RotZ,
                         real FocusDistance){
-    tnsCamera *c; tnsWorld *w = &T->World;
+    tnsCamera *c; tnsWorld *w = T->World;
 
     c = memAcquireHyper(sizeof(tnsCamera));
     tnsInitObjectBase(&c->Base, under, Name, TNS_OBJECT_CAMERA, AtX, AtY, AtZ, RotX, RotY, RotZ, 1.0f, TNS_ROTATION_XYZ_EULER, 1.0f);
@@ -3519,7 +3519,7 @@ tnsCamera *tnsCreateCamera(tnsObject *under, char *Name, real FOV,
     return c;
 }
 tnsObject *tnsCreateInstancer(tnsObject *under, char *Name, real AtX, real AtY, real AtZ){
-    tnsObject *o; tnsWorld *w = &T->World; if (!under) return 0;
+    tnsObject *o; tnsWorld *w = T->World; if (!under) return 0;
 
     o = memAcquireHyper(sizeof(tnsInstancer));
     tnsInitObjectBase(o, under, Name, TNS_OBJECT_INSTANCER, AtX, AtY, AtZ, 0, 0, 0, 1.0f, TNS_ROTATION_XYZ_EULER, 1.0f);
@@ -3527,7 +3527,7 @@ tnsObject *tnsCreateInstancer(tnsObject *under, char *Name, real AtX, real AtY,
     return o;
 }
 tnsLight *tnsCreateLight(tnsObject *under, char *Name, real AtX, real AtY, real AtZ, real Strength, int UniDirectional){
-    tnsLight *l; tnsWorld *w = &T->World; if (!under) return 0;
+    tnsLight *l; tnsWorld *w = T->World; if (!under) return 0;
     tnsObject* root=under->Type==TNS_OBJECT_ROOT?under:under->InRoot;
     if (UniDirectional&&under){
         if(root){ if(root->ParentObject) return root->ParentObject; }
@@ -3710,19 +3710,21 @@ void tnsEvaluateEmptyObject(tnsObject* o, tnsEvaluateData* ed){
 }
 void tnsPushEvaluateMatrixWith(tnsEvaluateData* ed, tnsMatrix44d mat){
     arrEnsureLength(&ed->MatArr,ed->NextMat,&ed->MaxMat,sizeof(tnsMatrix44d)); if(ed->NextMat<1) return;
-    real* new=ed->MatArr[ed->NextMat]; ed->NextMat++;
+    real* new=ed->MatArr[ed->NextMat];
     tnsMultiply44d(new, ed->MatArr[ed->NextMat-1], mat);
+    ed->NextMat++;
 }
 void tnsPopEvaluateMatrix(tnsEvaluateData* ed){ ed->NextMat--; }
 void tnsEvaluateInstancerObject(tnsInstancer* o, tnsEvaluateData* ed){
     int origid=ed->OverrideID; ed->OverrideID = o->Base.SelectID;
     tnsEvaluateEmptyObject(o,ed);
+    int origoutline=ed->FillOutline; ed->FillOutline=0;
     if(o->DefaultInstance){
         tnsPushEvaluateMatrixWith(ed,o->Base.GlobalTransform);
         tnsEvaluateObjectTree(o->DefaultInstance, ed);
         tnsPopEvaluateMatrix(ed);
     }
-    ed->OverrideID=origid;
+    ed->OverrideID=origid; ed->FillOutline=origoutline;
 }
 void tnsEvaluateThisObject(tnsObject *o, tnsEvaluateData* ed){
     if (!o->Show) return;
@@ -3776,14 +3778,14 @@ void tnsEvaluateObjectTree(tnsObject* from, tnsEvaluateData* UseED){
     if(!from) return;
     tnsEvaluateData* ed=UseED?UseED:(from->InRoot?(&from->InRoot->Evaluated):(&from->Evaluated));
     if(ed->Done) return;
-    else{ ed->NextCommand=ed->NextOverlay=ed->NextSelection=ed->NextOutline=ed->NextMat=0;
+    elif(!UseED){ ed->NextCommand=ed->NextOverlay=ed->NextSelection=ed->NextOutline=ed->NextMat=0;
         if(!ed->Commands) arrInitLength(&ed->Commands,16,&ed->MaxCommand,sizeof(tnsEvaluatedInstance));
         if(!ed->Outlines) arrInitLength(&ed->Outlines,16,&ed->MaxOutline,sizeof(tnsEvaluatedInstance));
         if(!ed->Overlays) arrInitLength(&ed->Overlays,16,&ed->MaxOverlay,sizeof(tnsEvaluatedInstance));
         if(!ed->Selections) arrInitLength(&ed->Selections,16,&ed->MaxSelection,sizeof(tnsEvaluatedInstance));
         if(!ed->MatArr) arrInitLength(&ed->MatArr,8,&ed->MaxMat,sizeof(tnsMatrix44d));
+        tnsLoadIdentity44d(ed->MatArr[0]); ed->NextMat=1;
     }
-    tnsLoadIdentity44d(ed->MatArr[0]); ed->NextMat=1;
     for (laListItemPointer* lip=from->ChildObjects.pFirst;lip;lip=lip->pNext){
         tnsObject *o=lip->p;
         tnsEvaluateThisObject(o, ed);
@@ -3791,8 +3793,7 @@ void tnsEvaluateObjectTree(tnsObject* from, tnsEvaluateData* UseED){
             tnsEvaluateObjectTree(o,ed);
         }
     }
-
-    ed->Done=1;
+    if(!UseED)ed->Done=1;
 }
 void tnsDrawLayer(tnsEvaluateData* ed,int Layer,void* CustomData){
     tnsEvaluatedInstance* ei; int next=0;
@@ -3851,12 +3852,12 @@ tnsMaterial *tnsCreateMaterial(char *Name){
 
     m = memAcquireHyper(sizeof(tnsMaterial));
     strSafeSet(&m->Name, Name);
-    lstAppendItem(&T->World.Materials, m);
+    lstAppendItem(&T->World->Materials, m);
     return m;
 }
 tnsMaterial *tnsFindMaterialByIndex(int index){
     tnsMaterial *m; int i = 0;
-    for (m = T->World.Materials.pFirst; m; m = m->Item.pNext){
+    for (m = T->World->Materials.pFirst; m; m = m->Item.pNext){
         if (i == index){ m->ID = i; return m; } i++;
     }
     return 0;
@@ -3864,7 +3865,7 @@ tnsMaterial *tnsFindMaterialByIndex(int index){
 tnsMaterial *tnsFindMaterial(char *name){
     tnsMaterial *m;
     int i = 0;
-    for (m = T->World.Materials.pFirst; m; m = m->Item.pNext){
+    for (m = T->World->Materials.pFirst; m; m = m->Item.pNext){
         if (strSame(m->Name->Ptr, name)){ return m; }
     }
     return 0;

+ 2 - 2
la_tns_mesh.c

@@ -315,7 +315,7 @@ void tnsDrawMeshObject(tnsEvaluatedInstance* ei, void* unused){
 void tnsEvaluateMeshObject(tnsMeshObject* mo, tnsEvaluateData* ed){
     tnsEnsureMeshBatch(mo);
     tnsAddEvaluatedInstance(ed,mo,tnsDrawMeshObject,TNS_EVAL_LAYER_SOLID,0,0,0);
-    if(ed->FillOutline){
+    if(ed->FillOutline && (!ed->OverrideID)){
         if((mo->Base.Flags&TNS_OBJECT_FLAGS_SELECTED) && (mo->Mode!=TNS_MESH_EDIT_MODE)){
             tnsAddEvaluatedInstance(ed,mo,tnsDrawMeshObjectOutline,TNS_EVAL_LAYER_OUTLINE,ed->Active==mo,0,0);
         }
@@ -323,7 +323,7 @@ void tnsEvaluateMeshObject(tnsMeshObject* mo, tnsEvaluateData* ed){
     if(ed->FillSelectionID){
         tnsAddEvaluatedInstance(ed,mo,tnsDrawMeshObjectSelectionID,TNS_EVAL_LAYER_SELECTION,0,1,mo->Base.SelectID);
     }
-    if(mo->Mode==TNS_MESH_EDIT_MODE){
+    if(mo->Mode==TNS_MESH_EDIT_MODE && (!ed->OverrideID)){
         tnsAddEvaluatedInstance(ed,mo,tnsDrawMeshObjectOverlay,TNS_EVAL_LAYER_OVERLAY,0,0,0);
     }
 }

+ 5 - 3
resources/la_modelling.c

@@ -157,14 +157,16 @@ void la_PopulateSelectDataPrimitives(MSelectData* sd, tnsMeshObject* mo, tnsCame
         glDepthMask(GL_TRUE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
         tnsUniformUseOffset(T->SelectionShader,0);
         tnsDrawBatch(mo->Batch,"body",0,0);
-        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_FALSE);
+        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
     }
+    glDepthMask(GL_FALSE);
     tnsUniformUseOffset(T->SelectionShader,1);
     if(DoEdges || Knife){ tnsDrawBatch(mo->Batch, "edges_select",0,0); }
     if(DoVerts || Knife){ tnsDrawBatch(mo->Batch, "verts_select",0,0); }
     tnsUniformUseOffset(T->SelectionShader,0);
     tnsPopMatrix();
     glDisable(GL_DEPTH_TEST);
+    tnsEnableShaderv(T->immShader);
 }
 void la_PadSelectionBuffer(uint8_t* buf, int w, int h, int sx, int sy, int ex, int ey, int real_endx){
     if(!sx&&!sy&&!ex&&!ey) return;
@@ -814,7 +816,7 @@ int OPINV_MakeParent(laOperator *a, laEvent *e){
 
     if(keep){
         la_MakeParentExecuteRecursive(root,mo,Unparent,KeepTransform);
-        laRecordInstanceDifferences(&T->World, "tns_world"); laPushDifferences(Unparent?"Unparent":"Parent", TNS_HINT_TRANSFORM);
+        laRecordInstanceDifferences(T->World, "tns_world"); laPushDifferences(Unparent?"Unparent":"Parent", TNS_HINT_TRANSFORM);
         return LA_FINISHED;
     }
     laEnableOperatorPanel(a,a->This,e->x,e->y,200,200,0,0,0,0,0,0,0,0,e);
@@ -1043,7 +1045,7 @@ int OPINV_Delete(laOperator *a, laEvent *e){
     
     if(mo->Base.Type!=TNS_OBJECT_MESH || mo->Mode!=TNS_MESH_EDIT_MODE){
         if(la_DeleteSelectedObjectsRecursive(root)){
-            laRecordInstanceDifferences(&T->World, "tns_world"); laPushDifferences("Deleted objects", TNS_HINT_TRANSFORM); laNotifyUsers("tns.world");
+            laRecordInstanceDifferences(T->World, "tns_world"); laPushDifferences("Deleted objects", TNS_HINT_TRANSFORM); laNotifyUsers("tns.world");
         }
     }else{
         if(!tnsMMeshAnySelected(mo)) return LA_FINISHED;

+ 11 - 27
resources/la_properties.c

@@ -536,12 +536,15 @@ void *tnsget_TnsMain(void *unused,void *unused2){
     return T;
 }
 void *tnsget_World(void *unused,void *unused2){
-    return &T->World;
+    return T->World;
 }
 void *tnsread_World(void *unused, void *inst){
 }
+void tnsset_InstancerDefaultInstance(tnsInstancer *o, tnsObject* value){
+    o->DefaultInstance=value; tnsInvalidateEvaluation(o); laNotifyUsers("tns.world");
+}
 void *tnsget_detached_FirstRootObject(void *UNUSED1, void *UNUSED2){
-    return T->World.RootObjects.pFirst;
+    return T->World->RootObjects.pFirst;
 }
 void *tnsget_detached_FirstTexture(void *UNUSED1, void *UNUSED2){
     return T->Textures.pFirst;
@@ -1332,38 +1335,18 @@ void la_RegisterInternalProps(){
             laAddIntProperty(p, "state", "State", "The Ui's Internal State", 0,0,0,0,0,1, 0,0,offsetof(laUiItem, State), 0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY);
             laAddIntProperty(p, "column_layout", "Column Layout", "The Ui's Column Layout", 0,0,0,10,-10,1, 0,0,offsetof(laUiItem, SymbolID), 0,0,0,0,0,0,0,0,0,0,0)
                 ->ElementBytes = sizeof(short);
-            //ep = laAddEnumProperty(p, "type", "Type", "The Type Of This Ui Item", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,LA_UDF_IGNORE);{
-            //    laAddEnumItemAs(ep, "button", "Button", "Button (Pure Operator)", LA_UI_INTERNAL_BUTTON, U'🔨');
-            //    laAddEnumItemAs(ep, "property_watcher", "Property Watcher", "Property Watcher For Int/Float/Enum", LA_UI_INTERNAL_WATCHER, U'🔑');
-            //    laAddEnumItemAs(ep, "group", "Group", "A Group That Holds A Sub-UiList", LA_UI_INTERNAL_GROUP, U'📁');
-            //    laAddEnumItemAs(ep, "tab", "Tab", "A Tab Root That Holds Multiple Sub-UiList", LA_UI_INTERNAL_TAB, U'📑');
-            //    laAddEnumItemAs(ep, "label", "Label", "A Static Label", LA_UI_INTERNAL_LABEL, 0);
-            //    laAddEnumItemAs(ep, "3d_view", "3D View", "Integrated 3D View UI Item", LA_UI_INTERNAL_3D_VIEW, 0);
-            //    laAddEnumItemAs(ep, "2d_view", "2D View", "Integrated 2D View UI Item", LA_UI_INTERNAL_2D_VIEW, U'🖻');
-            //    laAddEnumItemAs(ep, "column_adjuster", "Column Adjuster", "To Adjust Column Width", LA_UI_INTERNAL_ADJUSTER, U'↔');
-            //    laAddEnumItemAs(ep, "bracket_begin", "Bracket Begin", "Bracket Beginner Used To Set Ui Conditions", LA_UI_INTERNAL_BRACKET_BEGIN, '{');
-            //    laAddEnumItemAs(ep, "bracket_else", "Bracket Else", "Bracket Else Block Beginner", LA_UI_INTERNAL_BRACKET_ELSE, 0);
-            //    laAddEnumItemAs(ep, "folder_begin", "Folder Begin", "Folder Beginner Used To Toggle Some Display", LA_UI_INTERNAL_FOLDER_BEGIN, '{');
-            //    laAddEnumItemAs(ep, "bracket_end", "Bracket End", "Bracket Closer", LA_UI_INTERNAL_BRACKET_END, '}');
-            //    laAddEnumItemAs(ep, "aligner", "Aligner", "Align Column Heights", LA_UI_INTERNAL_ALIGNER, 0);
-            //    laAddEnumItemAs(ep, "menu", "Menu", "Menu Activiator", LA_UI_INTERNAL_MENU, U'🗩');
-            //}
             laAddStringProperty(p, "path", "Path", "Data Path", 0,0,0,0,0,0,0,laget_UiDataPath, 0,laread_UiDataPath,LA_READ_ONLY);
             laAddStringProperty(p, "actuator_id", "Operator ID", "Pure Operator With No 'This' Pointer", 0,0,0,0,0,0,0,laget_UiOperatorID, 0,laread_UiOperatorID,LA_READ_ONLY);
             laAddSubGroup(p, "pp", "Prop Pack", "Property Package In ui->PP Entry", "property_package",0,0,0,offsetof(laUiItem, PP), 0,0,0,0,0,0,0,LA_UDF_REFER);
             laAddSubGroup(p, "extra_pp", "Extra Prop Pack", "Property Package In ui->ExtraPP Entry", "property_package",0,0,0,offsetof(laUiItem, ExtraPP), 0,0,0,0,0,0,0,LA_UDF_REFER);
             laAddSubGroup(p, "go", "Prop Step Go", "Go Entry (For Determin If This Is A Prop Or Not)", "property_step",0,0,0,offsetof(laUiItem, PP.Go), 0,0,0,0,0,0,0,LA_UDF_REFER | LA_UDF_IGNORE);
             laAddSubGroup(p, "raw_this", "Prop Raw This", "ui->PP.RawThis Entry", "property_package",0,0,0,offsetof(laUiItem, PP.RawThis), 0,0,0,0,0,0,0,LA_UDF_REFER);
-            //ep = laAddSubGroup(p, "Ui Template", "A Template Used To Create Sub Ui", "ui_template",0,LA_WIDGET_COLLECTION_SELECTOR, 0,offsetof(laUiItem, Template), laget_PanelTemplate, 0,laget_ListNext, 0,0,0,0,0,0,LA_UDF_REFER);
-            //laSubGroupDetachable(ep, laget_UiTemplate, laget_ListNext);
             laAddSubGroup(p, "current_page", "Current Page", "Current Page In Sub Ui List", "ui_list",0,0,0,offsetof(laUiItem, Page), 0,0,0,0,0,0,0,LA_UDF_REFER);
             laAddSubGroup(p, "internal_type", "Ui Internal Type", "Ui Internal Type", "ui_type",0,0,0,offsetof(laUiItem, Type), 0,0,0,0,0,0,0,LA_UDF_REFER);
             laAddSubGroup(p, "on_column", "On Column", "Ui On Which Column", "ui_column",0,0,0,offsetof(laUiItem, C), 0,0,0,0,0,0,0,LA_UDF_REFER);
             laAddSubGroup(p, "sub", "Sub UI", "Sub Ui Lists For Tabs And Collection", "ui_list",0,0,0,-1, 0,0,0,0,0,0,offsetof(laUiItem, Subs), 0);
             laAddStringProperty(p, "extra_args", "Extra Arguments", "Extra Arguments For This Ui Item", 0,0,0,0,0,0,0,0,0,0,0);
             laAddStringProperty(p, "display", "Display", "Display String For Label", 0,0,0,0,0,0,0,0,0,0,0);
-            //laAddSubGroup(p, "Condition Ui Extra Data", "Condition Ui Extra Data For Linkage And Conditioning", "ui_condition_extra_data",0,0,0,offsetof(laUiItem, Extra), laget_ConditionerExtra, 0,0,0,0,0,0,0,0,0);
-            //laAddSubGroup(p, "2d_extra", "2D View Extra Data", "2D View Ui States And Modes Storage", 0,0,0,0,offsetof(laUiItem, Extra), laget_CanvasExtra, 0,0,0,0,0,0,0);
             laAddOperatorProperty(p, "maximize", "Maximize", "Maximize this UI item", "LA_canvas_ui_maximize", 0,0);
         }
 
@@ -1501,7 +1484,7 @@ void la_RegisterInternalProps(){
     // TNS WORLD ============================================================================================
 
     p = laAddPropertyContainer("tns_main", "TNS Main", "Render Kernel Root Structure", 0,0,sizeof(tnsMain), 0,0,2);{
-        laAddSubGroup(p, "world", "World", "World Descriptor", "tns_world",0,0,0,offsetof(tnsMain, World), 0,0,0,0,0,0,0,LA_UDF_SINGLE | LA_UDF_LOCAL);
+        laAddSubGroup(p, "world", "World", "World Descriptor", "tns_world",0,0,0,offsetof(tnsMain, World), 0,0,0,0,0,0,0,LA_UDF_SINGLE);
 
         sp = laAddSubGroup(p, "texture_list", "Texture List", "List Of All Textures Under TNS Management", "tns_texture",0,0,0,-1, 0,tnsget_PreviewTexture, 0,0,0,tnsset_PreviewTexture, offsetof(tnsMain, Textures), LA_UDF_IGNORE);
         laSubGroupDetachable(sp, tnsget_detached_FirstTexture, laget_ListNext);
@@ -1530,10 +1513,11 @@ void la_RegisterInternalProps(){
         p->Template2D = la_GetCanvasTemplate(0,"la_CanvasDrawTexture");
     }
 
-    p = laAddPropertyContainer("tns_world", "World", "3D World Structure", 0,0,sizeof(tnsWorld), 0,0,2|LA_PROP_OTHER_ALLOC);{
+    p = laAddPropertyContainer("tns_world", "World", "3D World Structure", 0,0,sizeof(tnsWorld), 0,0,1);{
         sp = laAddSubGroup(p, "root_objects", "Root Objects", "List of all root objects", "tns_object",0,0,0,-1,0,0,0,0,0,0,offsetof(tnsWorld, RootObjects), 0);
         laSubGroupDetachable(sp, tnsget_detached_FirstRootObject, laget_ListNext);
-        sp = laAddSubGroup(p, "objects", "Objects", "List of all objects", "tns_object",tnsget_ObjectType, 0,0,-1, 0,0,0,0,0,0,offsetof(tnsWorld, AllObjects), 0);
+        laAddSubGroup(p, "active_root", "Active Root Object", "Global active root object", "tns_object",0,0,0,offsetof(tnsWorld,ActiveRoot),tnsget_detached_FirstRootObject,0,laget_ListNext,0,0,0,0,LA_UDF_REFER);
+        sp = laAddSubGroup(p, "objects", "Objects", "List of all objects", "tns_object",tnsget_ObjectType, 0,0,-1,0,0,0,0,0,0,offsetof(tnsWorld, AllObjects), 0);
     }
 
     p = laAddPropertyContainer("tns_child_object", "Child Object", "Child object linker", 0,0,sizeof(laListItemPointer), 0,0,0);{
@@ -1590,8 +1574,8 @@ void la_RegisterInternalProps(){
         TNS_PC_OBJECT_INSTANCER=p;
         laAddStringProperty(p, "name", "Object Name", "The Name Of The Object", 0,0,0,0,1, offsetof(tnsObject, Name), 0,0,0,0,LA_AS_IDENTIFIER);
         laAddSubGroup(p, "base", "Base", "Object base", "tns_object",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
-        laAddSubGroup(p, "default_instance", "Instance", "Default instance to be used during editing", "tns_object",0,0,0,offsetof(tnsInstancer, DefaultInstance), 0,0,0,0,0,0,0,LA_UDF_REFER);
-        laAddSubGroup(p, "runtime_instance", "Runtime Instance", "Runtime instance, not saved", "tns_object",0,0,0,offsetof(tnsInstancer, RuntimeInstance), 0,0,0,0,0,0,0,LA_UDF_REFER|LA_UDF_IGNORE);
+        laAddSubGroup(p, "default_instance", "Instance", "Default instance to be used during editing", "tns_object",0,0,0,offsetof(tnsInstancer, DefaultInstance),tnsget_detached_FirstRootObject,0,laget_ListNext,tnsset_InstancerDefaultInstance,0,0,0,LA_UDF_REFER);
+        laAddSubGroup(p, "runtime_instance", "Runtime Instance", "Runtime instance, not saved", "tns_object",0,0,0,offsetof(tnsInstancer, RuntimeInstance),0,0,0,0,0,0,0,LA_UDF_REFER|LA_UDF_IGNORE|LA_READ_ONLY);
     }
     p = laAddPropertyContainer("tns_mesh_object", "Mesh Object", "Mesh object", 0,tnsui_MeshObjectProperties,sizeof(tnsMeshObject), tnspost_Object, 0,2);{
         laPropContainerExtraFunctions(p,0,0,tnstouched_Object,0/*tnspropagate_Object*/,0);

+ 63 - 48
resources/la_templates.c

@@ -1486,36 +1486,43 @@ void laui_Drivers(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *
     laSplitColumn(uil,cl,0.4); cll=laLeftColumn(cl,1); clr=laRightColumn(cl,0);
 
     laShowItemFull(uil,cll,Extra,"detached",0,0,0,0)->Flags|=LA_UI_FLAGS_HIGHLIGHT|LA_UI_FLAGS_ICON;
-    laUiItem* rb=laShowItemFull(uil,clr,Extra,"root_object",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
-
-    laUiItem* b2=laOnConditionThat(uil,cl,laPropExpression(&rb->PP,""));{
-
-        laUiItem* b=laBeginRow(uil,cr,0,0);
-        laUiItem* b3=laOnConditionThat(uil,cl,laPropExpression(&rb->PP,"drivers.current_page"));{
-            laShowItemFull(uil,cr,&rb->PP,"drivers.current_page",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0)
-                ->Flags|=LA_UI_COLLECTION_SIMPLE_SELECTOR;
-            laShowItem(uil,cr,&rb->PP,"drivers.current_page.name");
-            laShowItem(uil,cr,&rb->PP,"add_driver_page")->Flags|=LA_UI_FLAGS_ICON;
-            laShowSeparator(uil,cr);
-            laShowItem(uil,cr,&rb->PP,"drivers.current_page.trigger");
-            laShowItemFull(uil,cr,&rb->PP,"drivers.current_page.use_script",0,"icon=📃",0,0)
-                ->Flags|=LA_UI_FLAGS_HIGHLIGHT|LA_UI_FLAGS_CYCLE|LA_UI_FLAGS_ICON;
-        }laElse(uil,b3);{
-            laShowItem(uil,cr,&rb->PP,"add_driver_page")->Flags|=LA_UI_FLAGS_ICON;
-        }laEndCondition(uil,b3);
-        laEndRow(uil,b);
 
+#define ADD_PAGE \
+    laUiItem* b2=laOnConditionThat(uil,cl,laPropExpression(&rb->PP,""));{\
+        laUiItem* b=laBeginRow(uil,cr,0,0);\
+        laUiItem* b3=laOnConditionThat(uil,cl,laPropExpression(&rb->PP,"drivers.current_page"));{\
+            laShowItemFull(uil,cr,&rb->PP,"drivers.current_page",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0)\
+                ->Flags|=LA_UI_COLLECTION_SIMPLE_SELECTOR;\
+            laShowItem(uil,cr,&rb->PP,"drivers.current_page.name");\
+            laShowItem(uil,cr,&rb->PP,"add_driver_page")->Flags|=LA_UI_FLAGS_ICON;\
+            laShowSeparator(uil,cr);\
+            laShowItem(uil,cr,&rb->PP,"drivers.current_page.trigger");\
+            laShowItemFull(uil,cr,&rb->PP,"drivers.current_page.use_script",0,"icon=📃",0,0)\
+                ->Flags|=LA_UI_FLAGS_HIGHLIGHT|LA_UI_FLAGS_CYCLE|LA_UI_FLAGS_ICON;\
+        }laElse(uil,b3);{\
+            laShowItem(uil,cr,&rb->PP,"add_driver_page")->Flags|=LA_UI_FLAGS_ICON;\
+        }laEndCondition(uil,b3);\
+        laEndRow(uil,b);\
+    }laEndCondition(uil,b2);\
+    b2=laOnConditionThat(uil,c,laPropExpression(&rb->PP,"drivers.current_page"));{\
+        laUiItem* b3=laOnConditionThat(uil,c,laPropExpression(&rb->PP,"drivers.current_page.use_script"));{\
+            laShowItemFull(uil,c,&rb->PP,"drivers.current_page.script",0,0,0,0)->Extra->HeightCoeff=-2;\
+        }laElse(uil,b3);{\
+            laShowItemFull(uil,c,&rb->PP,"drivers.current_page",LA_WIDGET_COLLECTION_SINGLE,0,laui_RackPage,0)->Flags|=LA_UI_FLAGS_NO_DECAL;\
+        }laEndCondition(uil,b3);\
+    }laElse(uil,b2);{\
+        laShowLabel(uil,c,"Select or add a logic page.",0,0)->Flags|=LA_TEXT_ALIGN_CENTER;\
     }laEndCondition(uil,b2);
 
-    b2=laOnConditionThat(uil,c,laPropExpression(&rb->PP,"drivers.current_page"));{
-        laUiItem* b3=laOnConditionThat(uil,c,laPropExpression(&rb->PP,"drivers.current_page.use_script"));{
-            laShowItemFull(uil,c,Extra,"root_object.drivers.current_page.script",0,0,0,0)->Extra->HeightCoeff=-2;
-        }laElse(uil,b3);{
-            laShowItemFull(uil,c,Extra,"root_object.drivers.current_page",LA_WIDGET_COLLECTION_SINGLE,0,laui_RackPage,0)->Flags|=LA_UI_FLAGS_NO_DECAL;;
-        }laEndCondition(uil,b3);
-    }laElse(uil,b2);{
-        laShowLabel(uil,c,"Select or add a logic page.",0,0)->Flags|=LA_TEXT_ALIGN_CENTER;
-    }laEndCondition(uil,b2);
+    laUiItem* b1=laOnConditionThat(uil,c,laPropExpression(Extra,"detached"));{
+        laUiItem* rb=laShowItemFull(uil,clr,Extra,"root_object",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
+        ADD_PAGE
+    }laElse(uil,b1);{
+        laUiItem* rb=laShowItemFull(uil,clr,0,"tns.world.active_root",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
+        ADD_PAGE
+    }laEndCondition(uil,b1);
+
+#undef ADD_PAGE
 }
 
 void laui_AnimationActionSimple(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *ExtraColumns, int context){
@@ -1680,31 +1687,39 @@ void tnsui_ObjectProperties(laUiList *uil, laPropPack *This, laPropPack *Extra,
 
     laShowItemFull(uil,cl,Extra,"detached",0,0,0,0)->Flags|=LA_UI_FLAGS_HIGHLIGHT|LA_UI_FLAGS_ICON;
 
-    laUiItem* b=laBeginRow(uil,cr,0,0);
-
-    laUiItem* rb=laShowItemFull(uil,cr,Extra,"root_object",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
-    rb->Flags|=LA_UI_COLLECTION_SIMPLE_SELECTOR;
-
-    laUiItem* b2=laOnConditionThat(uil,cr,laPropExpression(&rb->PP,""));{
-        laShowItem(uil,cr,&rb->PP,"name")->Flags|=LA_UI_FLAGS_NO_DECAL;
-        laUiItem* b3=laOnConditionThat(uil,cr,laPropExpression(&rb->PP,"active"));{
-            laShowLabel(uil,cr,"⯈",0,0); laShowItem(uil,cr,&rb->PP,"active.name")->Flags|=LA_UI_FLAGS_NO_DECAL;
-        }laEndCondition(uil,b3);
-    }laEndCondition(uil,b2);
-
-    laEndRow(uil,b);
-
-    laUiItem* g; laUiList* gu; laColumn* gc;
+#define ADD_PAGE1(base,path) \
+    laUiItem* b=laBeginRow(uil,cr,0,0);\
+    laUiItem* rb=laShowItemFull(uil,cr,base,path,LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);\
+        rb->Flags|=LA_UI_COLLECTION_SIMPLE_SELECTOR;\
+    laUiItem* b2=laOnConditionThat(uil,cr,laPropExpression(&rb->PP,""));{\
+        laShowItem(uil,cr,&rb->PP,"name")->Flags|=LA_UI_FLAGS_NO_DECAL;\
+        laUiItem* b3=laOnConditionThat(uil,cr,laPropExpression(&rb->PP,"active"));{\
+            laShowLabel(uil,cr,"⯈",0,0); laShowItem(uil,cr,&rb->PP,"active.name")->Flags|=LA_UI_FLAGS_NO_DECAL;\
+        }laEndCondition(uil,b3);\
+    }laEndCondition(uil,b2);\
+    laEndRow(uil,b);\
+    laUiItem* g; laUiList* gu; laColumn* gc;\
     g=laMakeEmptyGroup(uil,c,"Object",0); gu=g->Page; gc=laFirstColumn(gu); g->Flags|=LA_UI_FLAGS_NO_DECAL;
 
-    b2=laOnConditionThat(gu,gc,laPropExpression(Extra,"detached"));{
+#define ADD_PAGE2 \
+    laUiItem* b3=laOnConditionThat(gu,gc,laPropExpression(&actui->PP,""));{\
+        tnsui_BaseObjectProperties(gu,&actui->PP,0,0,0);\
+    }laElse(gu,b3);{\
+        laShowLabel(gu,gc,"No active object.",0,0)->Flags|=LA_TEXT_ALIGN_CENTER|LA_UI_FLAGS_DISABLED;;\
+    }laEndCondition(gu,b3);
+
+    laUiItem* b0=laOnConditionThat(uil,c,laPropExpression(Extra,"detached"));{
+        ADD_PAGE1(Extra,"root_object")
         laUiItem* actui=laShowItem(gu,gc,&rb->PP,"active"); actui->Flags|=LA_UI_COLLECTION_NO_HIGHLIGHT|LA_UI_FLAGS_NO_DECAL;
-        tnsui_BaseObjectProperties(gu,&actui->PP,0,0,0);
-    }laElse(gu,b2);{
-        laUiItem* actui=laShowItemFull(gu,gc,0,"tns.world.root_objects",LA_WIDGET_COLLECTION_SINGLE,0,0,0);
+        ADD_PAGE2
+    }laElse(uil,b0);{
+        ADD_PAGE1(0,"tns.world.active_root")
+        laUiItem* actui=laShowItemFull(gu,gc,0,"tns.world.active_root.active",LA_WIDGET_COLLECTION_SINGLE,0,0,0);
         actui->Flags|=LA_UI_COLLECTION_NO_HIGHLIGHT|LA_UI_FLAGS_NO_DECAL;
-        tnsui_BaseObjectProperties(gu,&actui->PP,0,0,0);
-    }laEndCondition(gu,b2);
+        ADD_PAGE2
+    }laEndCondition(uil,b0);
+#undef ADD_PAGE1
+#undef ADD_PAGE2
 }
 
 void la_RegisterBuiltinTemplates(){

+ 1 - 1
resources/la_tns_drivers.c

@@ -150,7 +150,7 @@ int OPINV_RebuildDrivers(laOperator* a, laEvent *e){
 }
 
 tnsObject* tnsget_FirstObject(void* unused, void* unused2){
-    return T->World.AllObjects.pFirst;
+    return T->World->AllObjects.pFirst;
 }
 
 void tns_RegisterNodes(){