*/}}
1
0
YimingWu 1 rok pred
rodič
commit
3dcda0a0bf

+ 7 - 5
la_data.c

@@ -899,19 +899,21 @@ laProp *la_MakeDetachedProp(laPanel* p, const char *From, const char *Rename){
     switch (np->PropertyType){
     case LA_PROP_INT:
     case LA_PROP_INT | LA_PROP_ARRAY:
-        ip = np;
-        ip->Detached = CreateNewBuffer(int, np->Len ? np->Len : 1);
+        ip = np; if(!np->Len){ np->Len=1; }
+        ip->Detached = CreateNewBuffer(int, np->Len);
+        for(int i=0;i<np->Len;i++){ ((int*)ip->Detached)[i]=ip->DefVal; }
         break;
     case LA_PROP_FLOAT:
     case LA_PROP_FLOAT | LA_PROP_ARRAY:
-        fp = np;
-        fp->Detached = CreateNewBuffer(real, np->Len ? np->Len : 1);
+        fp = np; if(!np->Len){ np->Len=1; }
+        fp->Detached = CreateNewBuffer(real, np->Len);
+        for(int i=0;i<np->Len;i++){ ((real*)fp->Detached)[i]=fp->DefVal; }
         break;
     case LA_PROP_ENUM:
     case LA_PROP_ENUM | LA_PROP_ARRAY:
         ep = np;
         ep->Detached = CreateNewBuffer(int, 1);
-        ep->Detached[0] = ((laEnumItem *)ep->Items.pFirst)->Index;
+        ep->Detached[0] = ep->DefVal;
         break;
     case LA_PROP_SUB:
         sp=np; sp->GetCategory=((laSubProp*)np)->GetCategory;

+ 1 - 0
la_interface.h

@@ -1877,6 +1877,7 @@ void tnsui_LightObjectProperties(laUiList *uil, laPropPack *This, laPropPack *UN
 void tnsui_MeshObjectProperties(laUiList *uil, laPropPack *This, laPropPack *UNUSED_Extra, laColumn *UNUSED_Colums, int context);
 void tnsui_InstancerObjectProperties(laUiList *uil, laPropPack *This, laPropPack *UNUSED_Extra, laColumn *UNUSED_Colums, int context);
 void tnsui_BaseObjectProperties(laUiList *uil, laPropPack *This, laPropPack *UNUSED_Extra, laColumn *UNUSED_Colums, int context);
+void tnsui_RootObjectProperties(laUiList *uil, laPropPack *This, laPropPack *UNUSED_Extra, laColumn *UNUSED_Colums, int context);
 
 void tnsui_DefaultObjectPropUiDefine(laUiList *uil, laPropPack *This, laPropPack *OperatorProps, laColumn *UNUSED, int context);
 

+ 14 - 11
la_tns.h

@@ -160,6 +160,8 @@ struct _tnsWorld
     laListHandle Materials;
     laSafeString* MaterialLibraries;
 
+    int PropertyPage;
+
     u16bit TimeYear;
     u8bit TimeMonth;
     u8bit TimeDay;
@@ -520,18 +522,11 @@ STRUCTURE(tnsObject){
     int RotationMode;
     int IsInstanced;
 
-    real GLocation[3];
-    real GRotation[3];
-    real GScale[3];
-
-    real Location[3];
-    real Rotation[4];
-    real Scale[3];
+    real GLocation[3]; real GRotation[3]; real GScale[3];
+    real Location[3];  real Rotation[4];  real Scale[3];
 
     // delta transforms for animation & drivers.
-    real DLocation[3];
-    real DRotation[3];
-    real DScale[3];
+    real DLocation[3]; real DRotation[3]; real DScale[3];
 
     tnsMatrix44d GlobalTransform;
     tnsMatrix44d SelfTransform;
@@ -587,6 +582,13 @@ STRUCTURE(tnsMaterial){
 #define TNS_CAMERA_ORTHO 1
 #define TNS_CAMERA_FISHEYE 2
 
+STRUCTURE(tnsRootObject){
+    tnsObject Base;
+
+    int Is2D;
+    tnsObject* ActiveCamera;
+};
+
 STRUCTURE(tnsInstancer){
     tnsObject Base;
     
@@ -701,6 +703,7 @@ extern laPropContainer* TNS_PC_OBJECT_INSTANCER;
 extern laPropContainer* TNS_PC_OBJECT_CAMERA;
 extern laPropContainer* TNS_PC_OBJECT_LIGHT;
 extern laPropContainer* TNS_PC_OBJECT_MESH;
+extern laPropContainer* TNS_PC_OBJECT_ROOT;
 extern laPropContainer* TNS_PC_MATERIAL;
 extern laPropContainer* TNS_PC_MATERIAL_SLOT;
 
@@ -1067,7 +1070,7 @@ void *tnsget_detached_FirstRootObject(void *UNUSED1, void *UNUSED2);
 void tnsDestroyRootObject(tnsObject *root);
 void tnsDestroyObject(tnsObject *o);
 
-tnsObject *tnsCreateRootObject(char *name);
+tnsObject *tnsCreateRootObject(char *name, int Use2D);
 tnsCamera *tnsCreateCamera(tnsObject *under, char *Name, real FOV,
                               real AtX, real AtY, real AtZ,
                               real RotX, real RotY, real RotZ,

+ 9 - 8
la_tns_kernel.c

@@ -3431,7 +3431,7 @@ void tnsScaleObjectDelta(tnsObject *o, real x,real y,real z, real cx,real cy,rea
     tnsGlobalMatrixChangedForDelta(o,1);
 }
 void tnsZoomViewingCamera(tnsCamera *c, real Ratio){
-    if (c->FocusDistance < 0.1) return;
+    if (c->FocusDistance < 0.1 && Ratio > 0) return;
     tnsMoveObjectLocal(c, 0, 0, -c->FocusDistance * Ratio);
     c->FocusDistance *= (1 - Ratio);
 }
@@ -3469,17 +3469,17 @@ void tnsTranslateViewingCamera(tnsCamera *c, int ViewportW, int ViewportH, real
     tnsMoveObjectLocal(c, p[0], p[1], 0);
 }
 
-tnsObject *tnsCreateRootObject(char *name){
+tnsObject *tnsCreateRootObject(char *name, int Use2D){
     tnsWorld *w = T->World;
-    tnsObject *o = memAcquireHyper(sizeof(tnsObject));
+    tnsRootObject *o = memAcquireHyper(sizeof(tnsRootObject));
 
-    o->Type==TNS_OBJECT_ROOT;
-    strSafeSet(&o->Name, name);
+    o->Base.Type==TNS_OBJECT_ROOT;
+    strSafeSet(&o->Base.Name, name);
     lstAppendItem(&w->RootObjects, o);
-
     memAssignRef(w,&w->ActiveRoot,o);
 
-    o->Drivers=memAcquire(sizeof(laRackPageCollection));
+    o->Base.Drivers=memAcquire(sizeof(laRackPageCollection));
+    o->Is2D=Use2D;
 
     return o;
 }
@@ -3581,11 +3581,12 @@ tnsLight *tnsCreateLight(tnsObject *under, char *Name, real AtX, real AtY, real
 
 int tnsSizeOfObject(tnsObject* o){
     switch(o->Type){
-    case TNS_OBJECT_ROOT: default: return sizeof(tnsObject);
+    case TNS_OBJECT_ROOT: return sizeof(tnsRootObject);
     case TNS_OBJECT_INSTANCER: return sizeof(tnsInstancer);
     case TNS_OBJECT_MESH: return sizeof(tnsMeshObject);
     case TNS_OBJECT_CAMERA: return sizeof(tnsCamera);
     case TNS_OBJECT_LIGHT: return sizeof(tnsLight);
+    default: return sizeof(tnsObject);
     }
 }
 tnsObject* tnsDuplicateObject(tnsObject* o){

+ 3 - 1
resources/la_modelling.c

@@ -1620,7 +1620,9 @@ void laui_Merge(laUiList *uil, laPropPack *pp, laPropPack *actinst, laColumn *ex
 
 
 int OPINV_NewRootObject(laOperator *a, laEvent *e){
-    tnsCreateRootObject("Root"); laNotifyUsers("tns.world.root_objects"); laNotifyUsers("tns.world.active_root");
+    int use_2d=0;
+    if(strSame(strGetArgumentString(&a->ExtraInstructionsP,"type"),"2d")){ use_2d=1; }
+    tnsCreateRootObject("Root", use_2d); laNotifyUsers("tns.world.root_objects"); laNotifyUsers("tns.world.active_root");
     laRecordDifferences(0,"tns.world"); laPushDifferences("New root object",0);
     return LA_FINISHED;
 }

+ 22 - 1
resources/la_properties.c

@@ -580,6 +580,9 @@ void *tnsget_NextLinkedObject(tnsObject *o, laPropIterator *pi){
 void *tnsget_FirstChildObject(tnsObject *ob){
     return ob->ChildObjects.pFirst;
 }
+void tnsset_RootObjectIs2D(tnsRootObject *root, int Is2D){
+    root->Is2D=Is2D; laNotifyInstanceUsers(root);
+}
 
 void tnsset_ObjectLocation(tnsObject* o, int n, real val){ o->Location[n]=val;tnsSelfTransformValueChanged(o); laNotifyUsers("tns.world"); }
 void tnsset_ObjectRotation(tnsObject* o, int n, real val){ o->Rotation[n]=val; tnsSelfTransformValueChanged(o); laNotifyUsers("tns.world"); }
@@ -589,6 +592,7 @@ void tnsset_ObjectDRotationARR(tnsObject* o, real* arr){ tnsVectorCopy3d(arr,o->
 void tnsset_ObjectDScaleARR(tnsObject* o, real* arr){ tnsVectorCopy3d(arr,o->DScale); tnsDeltaTransformValueChanged(o); laNotifyUsers("tns.world"); }
 
 tnsMeshObject* tnsget_ObjectAsMesh(tnsObject* o){ if(!o || o->Type!=TNS_OBJECT_MESH) return 0; return o; }
+tnsRootObject* tnsget_ObjectAsRoot(tnsObject* o){ if(!o || o->Type!=TNS_OBJECT_ROOT) return 0; return o; }
 
 void laget_UiTemplateIdentifier(laUiTemplate *uit, char *result, char** here){
     *here=uit->Identifier->Ptr;
@@ -918,6 +922,7 @@ laPropContainer* tnsget_ObjectType(tnsObject* o){
     case TNS_OBJECT_CAMERA:    return TNS_PC_OBJECT_CAMERA;
     case TNS_OBJECT_MESH:      return TNS_PC_OBJECT_MESH;
     case TNS_OBJECT_LIGHT:     return TNS_PC_OBJECT_LIGHT;
+    case TNS_OBJECT_ROOT:      return TNS_PC_OBJECT_ROOT;
     default: return TNS_PC_OBJECT_GENERIC;
     }
 }
@@ -952,6 +957,7 @@ laPropContainer* TNS_PC_OBJECT_INSTANCER;
 laPropContainer* TNS_PC_OBJECT_CAMERA;
 laPropContainer* TNS_PC_OBJECT_LIGHT;
 laPropContainer* TNS_PC_OBJECT_MESH;
+laPropContainer* TNS_PC_OBJECT_ROOT;
 laPropContainer* TNS_PC_MATERIAL;
 laPropContainer* TNS_PC_MATERIAL_SLOT;
 
@@ -1070,6 +1076,10 @@ void la_RegisterTNSProps(){
         laSubGroupExtraFunctions(sp,tnsfilter_SavableObject,tnsfilter_SavableObject,0,0,0);
         sp = laAddSubGroup(p, "materials", "Materials", "List of all materials", "tns_material",0,0,0,-1,0,0,0,0,0,0,offsetof(tnsWorld, Materials), 0);
         laSubGroupDetachable(sp, tnsget_detached_FirstMaterial, laget_ListNext);
+        ep = laAddEnumProperty(p, "property_page", "Property Page", "Show which page in the properties panel", 0,0,0,1,0,offsetof(tnsWorld, PropertyPage), 0,0,0,0,0,0,0,0,0,LA_UDF_IGNORE);{
+            laAddEnumItemAs(ep, "ROOT", "Root", "Display root object properties",0,0);
+            laAddEnumItemAs(ep, "OBJECT", "Object", "Display object properties",1,0);
+        }
     }
 
     p = laAddPropertyContainer("tns_child_object", "Child Object", "Child object linker", 0,0,sizeof(laListItemPointer), 0,0,0);{
@@ -1149,6 +1159,18 @@ void la_RegisterTNSProps(){
         laAddOperatorProperty(p, "add_driver_page", "Add Page", "Add a driver page","LA_add_driver_page",'+',0);
         laAddOperatorProperty(p, "remove_root", "Remove root", "Remove the root node","M_remove_root",L'🗴',0);
         laAddSubGroup(p, "as_mesh", "As Mesh", "As mesh object", "tns_mesh_object",0,0,0,-1,0,tnsget_ObjectAsMesh,0,0,0,0,0,LA_UDF_REFER|LA_READ_ONLY|LA_UDF_IGNORE);
+        laAddSubGroup(p, "as_root_object", "As Root Object", "As root object", "tns_root_object",0,0,0,-1,0,tnsget_ObjectAsRoot,0,0,0,0,0,LA_UDF_REFER|LA_READ_ONLY|LA_UDF_IGNORE);
+    }
+    p = laAddPropertyContainer("tns_root_object", "Root Object", "Root object", 0, tnsui_RootObjectProperties,sizeof(tnsRootObject), 0,0,2);{
+        laPropContainerExtraFunctions(p,0,0,tnstouched_Object,0/*tnspropagate_Object*/,0);
+        TNS_PC_OBJECT_ROOT=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, "active_camera", "Active Camera", "Active camera of this root object", "tns_object",0,0,0,offsetof(tnsRootObject, ActiveCamera),0,0,0,0,0,0,0,LA_UDF_REFER|LA_READ_ONLY);
+        ep = laAddEnumProperty(p, "is_2d", "Is 2D", "Is 2D root object", 0,0,0,0,0,offsetof(tnsRootObject, Is2D), 0,tnsset_RootObjectIs2D,0,0,0,0,0,0,0,0);{
+            laAddEnumItemAs(ep, "3D", "3D", "Root object is in 3D", 0, 0);
+            laAddEnumItemAs(ep, "2D", "2D", "Root object is in 2D", 1, 0);
+        }
     }
     p = laAddPropertyContainer("tns_instancer", "Instancer", "Instance placeholder object", U'📎', tnsui_InstancerObjectProperties,sizeof(tnsInstancer), 0,0,2);{
         laPropContainerExtraFunctions(p,0,0,tnstouched_Object,0/*tnspropagate_Object*/,0);
@@ -1156,7 +1178,6 @@ void la_RegisterTNSProps(){
         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, "instance", "Instance", "Root object to be referenced", "tns_object",0,0,0,offsetof(tnsInstancer, Instance),tnsget_detached_FirstRootObject,0,laget_ListNext,tnsset_InstancerInstance,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);

+ 16 - 2
resources/la_templates.c

@@ -1877,6 +1877,12 @@ void tnsui_InstancerObjectProperties(laUiList *uil, laPropPack *This, laPropPack
     laSplitColumn(uil,c,0.5); cl=laLeftColumn(c,5); cr=laRightColumn(c,0);
     laShowLabel(uil,cl,"Instance",0,0); laShowItemFull(uil,cr,This,"instance",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
 }
+void tnsui_RootObjectProperties(laUiList *uil, laPropPack *This, laPropPack *UNUSED_Extra, laColumn *UNUSED_Colums, int context){
+    laColumn* c=laFirstColumn(uil), *cl,*cr;
+    laSplitColumn(uil,c,0.5); cl=laLeftColumn(c,5); cr=laRightColumn(c,0);
+    laShowLabel(uil,cl,"Mode",0,0); laShowItemFull(uil,cr,This,"is_2d",0,0,0,0)->Flags|=LA_UI_FLAGS_EXPAND;
+    laShowLabel(uil,cl,"Active Camera",0,0); laShowItemFull(uil,cr,This,"active_camera",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0);
+}
 void tnsui_BaseObjectProperties(laUiList *uil, laPropPack *This, laPropPack *UNUSED_Extra, laColumn *UNUSED_Colums, int context){
     laColumn* c=laFirstColumn(uil); laUiItem* g,*tg; laUiList* gu,*tu; laColumn* gc,*gcl,*gcr,*tc; laUiItem* b1,*b2,*b3,*b4,*b5;
     laShowLabel(uil,c,"Generic",0,0)->Flags|=LA_TEXT_ALIGN_CENTER|LA_UI_FLAGS_DISABLED; 
@@ -1898,6 +1904,7 @@ void tnsui_BaseObjectProperties(laUiList *uil, laPropPack *This, laPropPack *UNU
 void tnsuidetached_ObjectProperties(laPanel* p){
     la_MakeDetachedProp(p, "la.detached_view_switch", "detached");
     la_MakeDetachedProp(p, "tns.world.root_objects", "root_object");
+    la_MakeDetachedProp(p, "tns.world.property_page", "page");
 }
 void tnsui_ObjectProperties(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
     laColumn* c=laFirstColumn(uil);
@@ -1914,14 +1921,21 @@ void tnsui_ObjectProperties(laUiList *uil, laPropPack *This, laPropPack *Extra,
             laShowLabel(uil,c,"⯈",0,0); laShowItem(uil,c,&rb->PP,"active.name")->Flags|=LA_UI_FLAGS_NO_DECAL;\
         }laEndCondition(uil,b3);\
     }laEndCondition(uil,b2);\
-    laEndRow(uil,b);
+    laEndRow(uil,b);\
+    b=laBeginRow(uil,c,0,0);\
+    laShowItemFull(uil,c,Extra,"page",0,0,0,0)->Flags|=LA_UI_FLAGS_EXPAND;\
+    laEndRow(uil,b);\
+    b=laOnConditionThat(uil,c,laNot(laPropExpression(Extra,"page")));{\
+        laShowItemFull(uil,c,base,path ".as_root_object",LA_WIDGET_COLLECTION_SINGLE,0,0,0)->Flags|=LA_UI_FLAGS_NO_DECAL;\
+    }laElse(uil,b);
 
 #define ADD_PAGE2 \
     laUiItem* b3=laOnConditionThat(uil,c,laPropExpression(&actui->PP,""));{\
         tnsui_BaseObjectProperties(uil,&actui->PP,0,0,0);\
     }laElse(uil,b3);{\
         laShowLabel(uil,c,"No active object.",0,0)->Flags|=LA_TEXT_ALIGN_CENTER|LA_UI_FLAGS_DISABLED;;\
-    }laEndCondition(uil,b3);
+    }laEndCondition(uil,b3);\
+    laEndCondition(uil,b);
 
     laUiItem* b0=laOnConditionThat(uil,c,laPropExpression(Extra,"detached"));{
         ADD_PAGE1(Extra,"root_object")

+ 93 - 90
resources/la_widgets_viewers.c

@@ -25,6 +25,11 @@ extern struct _tnsMain *T;
 
 extern tnsFontManager *FM;
 
+void la_SetCanvasOrtho(laUiItem* ui){
+    laCanvasExtra* e=ui->Extra; int W, H; W = ui->R - ui->L; H = ui->B - ui->U;
+    real x2=(real)W*e->ZoomX/2,y2=(real)H*e->ZoomY/2;
+    tnsOrtho(e->PanX-x2,e->PanX+x2,e->PanY-y2,e->PanY+y2,100,-100);
+}
 
 void la_RootObjectDrawFullscreenQuad(tnsOffscreen* DeferredOffScr,tnsCamera* c, real Aspect){
     real FOV = c->FOV;
@@ -61,14 +66,10 @@ void la_RootObjectDraw(laBoxedTheme *bt, tnsObject *root, laUiItem* ui){
     laCanvasExtra *e = ui->Extra;
     la_3DViewEnsureCamera(e);
     tnsCamera *c = e->UsingCamera ? e->UsingCamera : e->ViewingCamera;
-    int W, H;
-    W = ui->R - ui->L;
-    H = ui->B - ui->U;
+    int W, H; W = ui->R - ui->L; H = ui->B - ui->U; if (W<=0 || H<=0) return;
 
     tnsFlush();
 
-    if (!W || !H) return;
-
     if (!e->OffScr){
         e->OffScr = tnsCreateDeferredOffscreen(W,H,MAIN.PanelMultisample);
         //e->OffScr = tnsCreate2DOffscreen(GL_RGBA, W, H, MAIN.PanelMultisample ,1, 0);
@@ -144,9 +145,11 @@ void la_RootObjectDraw(laBoxedTheme *bt, tnsObject *root, laUiItem* ui){
     tnsClearColorv(laThemeColor(bt,LA_BT_NORMAL)); tnsClearAll(); float gpos_clear[]={-1e20, -1e20, -1e20, 0};
     glClearBufferfv(GL_COLOR, 2, gpos_clear);
 
-    tnsApplyCameraView(W, H, c);
-    tnsPushMatrix();
-    tnsPopMatrix(); //those are necessary when ui is the first in list;
+    tnsRootObject* ro=root;
+    if(ro && ro->Is2D){ la_SetCanvasOrtho(ui); }
+    else{ tnsApplyCameraView(W, H, c); }
+
+    tnsPushMatrix(); tnsPopMatrix(); //those are necessary when ui is the first in list;
 
     laListHandle xrays={0};
 
@@ -286,7 +289,7 @@ void la_CanvasDrawTexture(laBoxedTheme *bt, tnsTexture *t, laUiItem* ui){
     tnsDrawToOffscreen(e->OffScr, 1, 0);
     tnsViewportWithScissor(0, 0, W, H);
     tnsResetViewMatrix();tnsResetModelMatrix();tnsResetProjectionMatrix();
-    tnsOrtho(e->PanX - W * e->ZoomX / 2, e->PanX + W * e->ZoomX / 2, e->PanY - e->ZoomY * H / 2, e->PanY + e->ZoomY * H / 2, 100, -100);
+    la_SetCanvasOrtho(ui);
 
     //glClearColor(0.3,0.3,0.3, 1);
     if (e->ClearBackground){ tnsClearColorv(laThemeColor(bt,LA_BT_NORMAL)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
@@ -591,25 +594,19 @@ void la_3DViewEnsureCamera(laCanvasExtra* e){
 void la_3DViewInit(laUiItem *ui){
     laCanvasExtra *e = ui->Extra;
 
-    if (e){
-        return;
-    }else{
-        e = memAcquireHyper(sizeof(laCanvasExtra));
-    }
+    if (e){ return; }
+    else{ e = memAcquireHyper(sizeof(laCanvasExtra)); ui->Extra = e; }
+
+    la_CanvasInit(ui);
 
-    ui->Extra = e;
     e->ParentUi = ui;
 
     la_3DViewEnsureCamera(e);
 
-    e->ShowAxis[0] = 1;
-    e->ShowAxis[1] = 1;
+    e->ShowAxis[0] = 1; e->ShowAxis[1] = 1;
     e->ShowFloorGrid = 1;
-
     e->HeightCoeff = 10;
 
-    laFirstColumn(laAddTabPage(ui, "New Group"));
-
     laRecordDifferences(0,"tns.world");
     laPushDifferences("Created camera for 3D view widget,",0);
 }
@@ -682,8 +679,7 @@ void la_CanvasInit(laUiItem *ui){
     e->ParentUi = ui;
 
     e->HeightCoeff = 10;
-    e->ZoomX = 1;
-    e->ZoomY = 1;
+    e->ZoomX = 1; e->ZoomY = 1;
     e->ImageDrawAlpha = 1;
     e->ImageDrawBorder = 1;
     e->AdaptiveLineWidth = 1;
@@ -807,74 +803,6 @@ int OPMOD_Canvas(laOperator *a, laEvent *e){
     return LA_RUNNING_PASS;
 }
 
-int OPCHK_Is3DViewExtra(laPropPack *This, laStringSplitor *ss){
-    if (This && This->LastPs->p->SubProp == _LA_PROP_3D_EXTRA) return 1;
-    return 0;
-}
-int OPINV_3DViewCameraZoom(laOperator *a, laEvent *e){
-    laCanvasExtra *ex = a->This->EndInstance;
-    tnsCamera *c = ex->ViewingCamera;
-
-    if (strArgumentMatch(a->ExtraInstructionsP, "direction", "in")){
-        tnsZoomViewingCamera(c, 0.1);
-        laRedrawCurrentPanel();
-    }elif (strArgumentMatch(a->ExtraInstructionsP, "direction", "out")){
-        tnsZoomViewingCamera(c, -0.1);
-        laRedrawCurrentPanel();
-    }
-
-    return LA_FINISHED;
-}
-int OPINV_3DOr2DViewAdjust(laOperator *a, laEvent *e){
-    laGeneralUiExtraData *ex = memAcquireSimple(sizeof(laGeneralUiExtraData));
-    laSetWindowCursor(LA_HAND);
-    a->CustomData = ex;
-    ex->LastX = e->x;
-    ex->LastY = e->y;
-
-    return LA_RUNNING;
-}
-int OPEXT_3DOr2DViewAdjust(laOperator *a, int Mark){
-    if (a->CustomData) memFree(a->CustomData);
-    laSetWindowCursor(LA_ARROW);
-}
-int OPMOD_3DViewCameraRotate(laOperator *a, laEvent *e){
-    laCanvasExtra *ex = a->This->EndInstance;
-    laGeneralUiExtraData *uex = a->CustomData;
-
-    if (e->Type == LA_L_MOUSE_UP || e->Type == LA_M_MOUSE_UP || e->Type == LA_R_MOUSE_DOWN) return LA_FINISHED;
-
-    if (e->Type == LA_MOUSEMOVE){
-        tnsRotateViewingCamera(ex->ViewingCamera, (real)(uex->LastY - e->y) / 150.0, (real)(uex->LastX - e->x) / 150.0);
-        uex->LastX = e->x;
-        uex->LastY = e->y;
-        laRedrawCurrentPanel();
-    }
-
-    return LA_RUNNING;
-}
-int OPMOD_3DViewCameraMove(laOperator *a, laEvent *e){
-    laCanvasExtra *ex = a->This->EndInstance;
-    laGeneralUiExtraData *uex = a->CustomData;
-
-    if (e->Type == LA_L_MOUSE_UP || e->Type == LA_M_MOUSE_UP || e->Type == LA_R_MOUSE_DOWN){
-        laSetWindowCursor(LA_ARROW);
-        return LA_FINISHED;
-    }
-    if (e->Type == LA_MOUSEMOVE){
-        tnsTranslateViewingCamera(ex->ViewingCamera, ex->ParentUi->R - ex->ParentUi->L, ex->ParentUi->B - ex->ParentUi->U, -e->x + uex->LastX, e->y - uex->LastY);
-        //tnsTranslateObjectLocal(ex->ViewingCamera,
-        //	-(real)(e->x - uex->LastX) * ex->ViewingCamera->FocusDistance / 100,
-        //	(real)(e->y - uex->LastY) * ex->ViewingCamera->FocusDistance / 100,
-        //	0);
-        uex->LastX = e->x;
-        uex->LastY = e->y;
-        laRedrawCurrentPanel();
-    }
-
-    return LA_RUNNING;
-}
-
 int OPCHK_Is2DViewExtra(laPropPack *This, laStringSplitor *ss){
     return 1;
     //if (This && (This->LastPs->p->SubProp == _LA_PROP_2D_EXTRA)) return 1;
@@ -977,6 +905,81 @@ int OPINV_CanvasClick(laOperator *a, laEvent *e){
     return LA_FINISHED_PASS;
 }
 
+
+int OPCHK_Is3DViewExtra(laPropPack *This, laStringSplitor *ss){
+    if (This && This->LastPs->p->SubProp == _LA_PROP_3D_EXTRA) return 1;
+    return 0;
+}
+int OPINV_3DViewCameraZoom(laOperator *a, laEvent *e){
+    laCanvasExtra *ex = a->This->EndInstance;
+    tnsCamera *c = ex->ViewingCamera;
+    laUiItem* ui=ex->ParentUi; tnsRootObject* root=ui->PP.EndInstance;
+    if(root && root->Base.Type==TNS_OBJECT_ROOT && root->Is2D){
+        return OPINV_CanvasZoom(a,e);
+    }
+
+    if (strArgumentMatch(a->ExtraInstructionsP, "direction", "in")){
+        tnsZoomViewingCamera(c, 0.1);
+        laRedrawCurrentPanel();
+    }elif (strArgumentMatch(a->ExtraInstructionsP, "direction", "out")){
+        tnsZoomViewingCamera(c, -0.1);
+        laRedrawCurrentPanel();
+    }
+
+    return LA_FINISHED;
+}
+int OPINV_3DOr2DViewAdjust(laOperator *a, laEvent *e){
+    laGeneralUiExtraData *ex = memAcquireSimple(sizeof(laGeneralUiExtraData));
+    laSetWindowCursor(LA_HAND);
+    a->CustomData = ex;
+    ex->LastX = e->x; ex->LastY = e->y;
+
+    return LA_RUNNING;
+}
+int OPEXT_3DOr2DViewAdjust(laOperator *a, int Mark){
+    if (a->CustomData) memFree(a->CustomData);
+    laSetWindowCursor(LA_ARROW);
+}
+int OPMOD_3DViewCameraRotate(laOperator *a, laEvent *e){
+    laCanvasExtra *ex = a->This->EndInstance;
+    laGeneralUiExtraData *uex = a->CustomData;
+    laUiItem* ui=ex->ParentUi; tnsRootObject* root=ui->PP.EndInstance;
+    if(root && root->Base.Type==TNS_OBJECT_ROOT && root->Is2D){
+        return OPMOD_CanvasMove(a,e);
+    }
+
+    if (e->Type == LA_L_MOUSE_UP || e->Type == LA_M_MOUSE_UP || e->Type == LA_R_MOUSE_DOWN) return LA_FINISHED;
+
+    if (e->Type == LA_MOUSEMOVE){
+        tnsRotateViewingCamera(ex->ViewingCamera, (real)(uex->LastY - e->y) / 150.0, (real)(uex->LastX - e->x) / 150.0);
+        uex->LastX = e->x;
+        uex->LastY = e->y;
+        laRedrawCurrentPanel();
+    }
+
+    return LA_RUNNING;
+}
+int OPMOD_3DViewCameraMove(laOperator *a, laEvent *e){
+    laCanvasExtra *ex = a->This->EndInstance;
+    laGeneralUiExtraData *uex = a->CustomData;
+    laUiItem* ui=ex->ParentUi; tnsRootObject* root=ui->PP.EndInstance;
+    if(root && root->Base.Type==TNS_OBJECT_ROOT && root->Is2D){
+        return LA_FINISHED;
+    }
+
+    if (e->Type == LA_L_MOUSE_UP || e->Type == LA_M_MOUSE_UP || e->Type == LA_R_MOUSE_DOWN){
+        laSetWindowCursor(LA_ARROW);
+        return LA_FINISHED;
+    }
+    if (e->Type == LA_MOUSEMOVE){
+        tnsTranslateViewingCamera(ex->ViewingCamera, ex->ParentUi->R - ex->ParentUi->L, ex->ParentUi->B - ex->ParentUi->U, -e->x + uex->LastX, e->y - uex->LastY);
+        uex->LastX = e->x; uex->LastY = e->y;
+        laRedrawCurrentPanel();
+    }
+
+    return LA_RUNNING;
+}
+
 void la_RegisterViewerOperators(){
     laCreateOperatorType("LA_canvas_operator", "2D View UiItem Operator", "All Visual 2D View Operations Are Called From This Ui",
                           0, 0, OPEXT_3DOr2DViewUiItem, OPINV_3DOr2DViewUiItem, OPMOD_Canvas, U'🖦', LA_EXTRA_TO_PANEL | LA_ACTUATOR_SYSTEM | LA_ACTUATOR_HIDDEN);