*/}}
Browse Source

Material and file stuff optimization

YimingWu 8 months ago
parent
commit
3db7b50d8d

+ 18 - 21
la_data.c

@@ -2558,26 +2558,23 @@ int la_ReadIntProp(laUDF *udf, laPropPack *pp){
         return Data[0];
     }
     p = pp->LastPs->p;
-    if (p->PropertyType & LA_PROP_ARRAY){
-        la_ReadShort(udf); //mark
-        len = la_ReadShort(udf);
-        //len = laGetArrayLength(pp);
-        for (i = 0; i < len; i++){
-            Data[i] = la_ReadInt(udf);
-        }
-        laReadIntArrayAllArray(pp, Data);
+    short mark=la_ReadShort(udf);
+    if(mark==LA_UDF_ARRAY_MARK_64 || mark==LA_UDF_ARRAY_MARK_32){ len = la_ReadShort(udf);
+        for(i=0;i<len;i++){ Data[i] = la_ReadInt(udf); }
     }else{
-        la_ReadShort(udf);
         Data[0] = la_ReadInt(udf);
-        laReadInt(pp, Data[0]);
+    }
+    if (p->PropertyType & LA_PROP_ARRAY){
+        if (pp) laReadIntArrayAllArray(pp, Data);
+    }else{
+        if (pp) laReadInt(pp, Data[0]);
     }
     return Data[0];
 }
 real la_ReadFloatProp(laUDF *udf, laPropPack *pp){
     laProp *p;
     real Data[16] = {0};
-    int len = 0;
-    int i;
+    int len = 0; int i;
     if (!pp){
         int mode = la_ReadShort(udf);
         if (mode == LA_UDF_ARRAY_MARK_64){
@@ -2589,17 +2586,15 @@ real la_ReadFloatProp(laUDF *udf, laPropPack *pp){
         return Data[0];
     }
     p = pp->LastPs->p;
+    short mark=la_ReadShort(udf);
+    if(mark==LA_UDF_ARRAY_MARK_64 || mark==LA_UDF_ARRAY_MARK_32){ len = la_ReadShort(udf);
+        for(i=0;i<len;i++){ Data[i] = la_ReadFloat(udf); }
+    }else{
+        Data[0] = la_ReadFloat(udf);
+    }
     if (p->PropertyType & LA_PROP_ARRAY){
-        la_ReadShort(udf); //mark
-        len = la_ReadShort(udf);
-        //len = laGetArrayLength(pp);
-        for (i = 0; i < len; i++){
-            Data[i] = la_ReadFloat(udf);
-        }
         if (pp) laReadFloatArrayAllArray(pp, Data);
     }else{
-        la_ReadShort(udf);
-        Data[0] = la_ReadFloat(udf);
         if (pp) laReadFloat(pp, Data[0]);
     }
     return Data[0];
@@ -3298,7 +3293,9 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
                         int IsItem=((laSubProp*)p)->ListHandleOffset?1:0;
                         RealSize = RealSize ? RealSize : p->SubProp->NodeSize;
                         if (!Parent && !IsExceptionNode){
-                            if (p->UDFIsSingle && pp->EndInstance){ Instance = pp->EndInstance; la_ResetInstance(Instance, pc, IsItem); replaced=1; }
+                            if (p->UDFIsSingle && (pp->EndInstance=laGetActiveInstanceStrict(pp->LastPs->p,pp->LastPs->UseInstance))){ 
+                                Instance = pp->EndInstance; la_ResetInstance(Instance, pc, IsItem); replaced=1;
+                            }
                             else{
                                 // if overwrite, find the instance here for hyper2, if not Hyper 2 then notice can't overwrite.
                                 if (pc->Hyper == 2){

+ 5 - 0
la_interface.h

@@ -889,6 +889,7 @@ STRUCTURE(laMultiStringExtra){
 NEED_STRUCTURE(laCanvasExtra);
 
 STRUCTURE(la3DObjectDrawExtra){
+    int DisplayMode;
     int MeshEditType;
 };
 
@@ -926,6 +927,9 @@ STRUCTURE(laCanvasTemplate){
 #define LA_CANVAS_SELECT_THROUGH_OFF 0
 #define LA_CANVAS_SELECT_THROUGH_ON  1
 
+#define LA_CANVAS_DISPLAY_SOLID 0
+#define LA_CANVAS_DISPLAY_MATERIAL 1
+
 void la_CanvasDefaultOverlay(laUiItem* ui, int h);
 void la_CanvasDrawOverlay(laUiItem *ui, int h);
 void la_CanvasInit(laUiItem *ui);
@@ -981,6 +985,7 @@ STRUCTURE(laCanvasExtra){
 
     int ShowFloorGrid;
     int ShowAxis[3];
+    int DisplayMode;
 };
 
 NEED_STRUCTURE(laUiConditionNode);

+ 1 - 1
la_kernel.c

@@ -4448,7 +4448,7 @@ int la_DoExpression(laUiConditionNode *Expression, int *IResult, real *FResult,
             break;
         case LA_PROP_SUB:
             sp=Expression->PP.LastPs->p;
-            if (sp->IsDetached){ *PtrResult = sp->Detached; if (sp->Detached) return 1; else return 0; }
+            //if (sp->IsDetached){ *PtrResult = sp->Detached; if (sp->Detached) return 1; else return 0; }
             if (!Expression->PP.Go) Instance = Expression->PP.EndInstance;
             else Instance = laGetActiveInstance(Expression->PP.LastPs->p, Expression->PP.LastPs->UseInstance, &pi);
             if(!Instance){ Expression->PP.LastPs->p; if((!sp->GetActive) && (sp->Base.Offset<=0)){ 

+ 6 - 9
la_tns.h

@@ -521,16 +521,16 @@ STRUCTURE(tnsObject){
 
     real GLocation[3];
     real GRotation[3];
-    real GScale;//Only allow uniform scale
+    real GScale[3];
 
     real Location[3];
     real Rotation[4];
-    real Scale;
+    real Scale[3];
 
     // delta transforms for animation & drivers.
     real DLocation[3];
     real DRotation[3];
-    real DScale;
+    real DScale[3];
 
     tnsMatrix44d GlobalTransform;
     tnsMatrix44d SelfTransform;
@@ -572,9 +572,6 @@ STRUCTURE(tnsMakeTransformNode){
 #define TNS_ID_TO_COLOR(color, i) \
     {color[0]=(real)((i & 0x000000FF)>>0)/255.0; color[1]=(real)((i & 0x0000FF00)>>8)/255.0; color[2]=(real)((i & 0x00FF0000)>>16)/255.0;}
 
-#define TNS_MATERIAL_DRAW_MODE_SOLID 0
-#define TNS_MATERIAL_DRAW_MODE_WIRE 1
-
 STRUCTURE(tnsMaterial){
     laListItem Item;
     laSafeString *Name;
@@ -1006,7 +1003,7 @@ int tnsIntersectPlaneRay(tnsVector3d n, tnsVector3d p0, tnsVector3d l0, tnsVecto
 
 void tnsExtractXYZEuler44d(tnsMatrix44d mat, real *xyz_result);
 void tnsExtractLocation44d(tnsMatrix44d mat, real *xyz_result);
-void tnsExtractUniformScale44d(tnsMatrix44d mat, real *uniform_result);
+void tnsExtractScale44d(tnsMatrix44d mat, real *xyz_result);
 void tnsSelfMatrixChanged(tnsObject* o, int ApplyToChild);
 void tnsGlobalMatrixChanged(tnsObject* o, int ApplyToChild);
 void tnsGlobalMatrixChangedForDelta(tnsObject* o, int ApplyToChild);
@@ -1051,8 +1048,8 @@ void tnsMoveObjectLocal(tnsObject *o, real x, real y, real z);
 void tnsMoveObjectDelta(tnsObject *o, real x, real y, real z);
 void tnsMoveObjectGlobal(tnsObject *o, real x, real y, real z);
 void tnsMoveObjectGlobalForDelta(tnsObject *o, real x, real y, real z);
-void tnsScaleObject(tnsObject *o, real fac, real cx,real cy,real cz);
-void tnsScaleObjectDelta(tnsObject *o, real fac, real cx,real cy,real cz);
+void tnsScaleObject(tnsObject *o, real x,real y,real z, real cx,real cy,real cz);
+void tnsScaleObjectDelta(tnsObject *o, real x,real y,real z, real cx,real cy,real cz);
 int tnsCheckParentable(tnsObject* child, tnsObject* parent);
 void tnsParentObject(tnsObject *child, tnsObject *parent, int KeepTransform);
 void tnsUnparentObject(tnsObject *o, int KeepTransform);

+ 35 - 36
la_tns_kernel.c

@@ -866,8 +866,12 @@ void tnsClearTranslation44d(tnsMatrix44d mat){
     mat[11] = 0;
 }
 
-void tnsExtractXYZEuler44d(tnsMatrix44d mat, real *xyz_result){
+void tnsExtractXYZEuler44d(tnsMatrix44d _mat, real *xyz_result){
     real xRot, yRot, zRot;
+    tnsMatrix44d mat; tnsCopyMatrix44d(_mat,mat);
+    tnsNormalizeSelf3d(&mat[0]);
+    tnsNormalizeSelf3d(&mat[4]);
+    tnsNormalizeSelf3d(&mat[8]);
 
     if (mat[2] < 1){
         if (mat[2] > -1){
@@ -894,9 +898,10 @@ void tnsExtractLocation44d(tnsMatrix44d mat, real *xyz_result){
     xyz_result[1] = mat[13];
     xyz_result[2] = mat[14];
 }
-void tnsExtractUniformScale44d(tnsMatrix44d mat, real *uniform_result){
-    tnsVector3d v = {mat[0], mat[1], mat[2]};
-    *uniform_result = tnsLength3d(v);
+void tnsExtractScale44d(tnsMatrix44d mat, real *xyz_result){
+    xyz_result[0] = tnsLength3d(&mat[0]);
+    xyz_result[1] = tnsLength3d(&mat[4]);
+    xyz_result[2] = tnsLength3d(&mat[8]);
 }
 
 #define L(row, col) l[(col << 2) + row]
@@ -1113,9 +1118,7 @@ void tnsMakeRotationZMatrix44d(tnsMatrix44d m, real angle_rad){
 }
 void tnsMakeScaleMatrix44d(tnsMatrix44d m, real x, real y, real z){
     tnsLoadIdentity44d(m);
-    m[0] = x;
-    m[5] = y;
-    m[10] = z;
+    m[0] = x; m[5] = y; m[10] = z;
 }
 void tnsMakeViewportMatrix44d(tnsMatrix44d m, real w, real h, real Far, real Near){
     tnsLoadIdentity44d(m);
@@ -3111,25 +3114,25 @@ void tnsExtractDeltaTransformValue(tnsObject *o){
     if (!o) return;
     tnsExtractLocation44d(o->DeltaTransform, o->DLocation);
     tnsExtractXYZEuler44d(o->DeltaTransform, o->DRotation);
-    tnsExtractUniformScale44d(o->DeltaTransform, &o->DScale);
+    tnsExtractScale44d(o->DeltaTransform, o->DScale);
 }
 void tnsExtractSelfTransformValue(tnsObject *o){
     if (!o) return;
     tnsExtractLocation44d(o->SelfTransform, o->Location);
     tnsExtractXYZEuler44d(o->SelfTransform, o->Rotation);
-    tnsExtractUniformScale44d(o->SelfTransform, &o->Scale);
+    tnsExtractScale44d(o->SelfTransform, o->Scale);
 }
 void tnsExtractGlobalTransformValue(tnsObject *o){
     if (!o) return;
     tnsExtractLocation44d(o->GlobalTransform, o->GLocation);
     tnsExtractXYZEuler44d(o->GlobalTransform, o->GRotation);
-    tnsExtractUniformScale44d(o->GlobalTransform, &o->GScale);
+    tnsExtractScale44d(o->GlobalTransform, o->GScale);
 }
 void tnsCopyGlobalTransform(tnsObject *to, tnsObject *from){
     memcpy(to->GlobalTransform, from->GlobalTransform, sizeof(tnsMatrix44d));
     memcpy(to->GLocation, from->GLocation, sizeof(tnsVector3d));
     memcpy(to->GRotation, from->GRotation, sizeof(tnsVector3d));
-    to->GScale = from->GScale;
+    memcpy(to->GScale, from->GScale, sizeof(tnsVector3d));
     tnsGlobalTransformValueChanged(to);
 }
 
@@ -3176,7 +3179,10 @@ void tnsSelfTransformValueChanged(tnsObject* o){
     tnsMatrix44d Trans, Rot1, Rot2, Rot3, Scale, Res1, Res2;
     tnsLoadIdentity44d(o->SelfTransform);
     tnsMakeTranslationMatrix44d(Trans, LA_COLOR3(o->Location));
-    tnsMakeScaleMatrix44d(Scale, o->Scale,o->Scale,o->Scale);
+    if(o->Scale[0]<1e-5){ o->Scale[0]=1e-5; }
+    if(o->Scale[1]<1e-5){ o->Scale[1]=1e-5; }
+    if(o->Scale[2]<1e-5){ o->Scale[2]=1e-5; }
+    tnsMakeScaleMatrix44d(Scale, LA_COLOR3(o->Scale));
 
     tnsMakeRotationXMatrix44d(Rot1, o->Rotation[0]);
     tnsMakeRotationYMatrix44d(Rot2, o->Rotation[1]);
@@ -3196,7 +3202,7 @@ void tnsDeltaTransformValueChanged(tnsObject* o){
     tnsMatrix44d Trans, Rot1, Rot2, Rot3, Scale, Res1, Res2;
     tnsLoadIdentity44d(o->DeltaTransform);
     tnsMakeTranslationMatrix44d(Trans, LA_COLOR3(o->DLocation));
-    tnsMakeScaleMatrix44d(Scale, o->DScale,o->DScale,o->DScale);
+    tnsMakeScaleMatrix44d(Scale, LA_COLOR3(o->DScale));
 
     tnsMakeRotationXMatrix44d(Rot1, o->DRotation[0]);
     tnsMakeRotationYMatrix44d(Rot2, o->DRotation[1]);
@@ -3216,7 +3222,7 @@ void tnsGlobalTransformValueChanged(tnsObject* o){
     tnsMatrix44d Trans, Rot1, Rot2, Rot3, Scale, Res1, Res2;
     tnsLoadIdentity44d(o->GlobalTransform);
     tnsMakeTranslationMatrix44d(Trans, LA_COLOR3(o->GLocation));
-    tnsMakeScaleMatrix44d(Scale, o->GScale,o->GScale,o->GScale);
+    tnsMakeScaleMatrix44d(Scale, LA_COLOR3(o->GScale));
 
     tnsMakeRotationXMatrix44d(Rot1, o->GRotation[0]);
     tnsMakeRotationYMatrix44d(Rot2, o->GRotation[1]);
@@ -3244,15 +3250,9 @@ void tnsInitObjectBase(tnsObject *o, tnsObject *under, char *Name, int Type,
     if (!o) return;
     strSafeSet(&o->Name, Name);
     o->Type = Type;
-    o->Location[0] = AtX;
-    o->Location[1] = AtY;
-    o->Location[2] = AtZ;
-    o->Rotation[0] = RotX;
-    o->Rotation[1] = RotY;
-    o->Rotation[2] = RotZ;
-    o->Rotation[3] = RotW;
-    o->RotationMode = RotationMode;
-    o->Scale = Scale;
+    tnsVectorSet3(o->Location,AtX,AtY,AtZ);
+    tnsVectorSet4(o->Rotation,RotX,RotY,RotZ,RotW); o->RotationMode = RotationMode;
+    tnsVectorSet3(o->Scale,Scale,Scale,Scale);
     o->Show = 1;
     o->DrawMode = GL_LINE_LOOP;
     tnsLoadIdentity44d(o->DeltaTransform);
@@ -3290,13 +3290,13 @@ void tnsUnparentObject(tnsObject *o, int KeepTransform){
 void tnsCopyObjectTransformationsLocal(tnsObject* to, tnsObject* from){
     tnsVectorCopy3d(from->Location, to->Location);
     tnsVectorCopy3d(from->Rotation, to->Rotation); to->RotationMode=from->RotationMode;
-    to->Scale = from->Scale;
+    tnsVectorCopy3d(from->Scale, to->Scale); 
     tnsSelfTransformValueChanged(to);
 }
 void tnsCopyObjectTransformationsGlobal(tnsObject* to, tnsObject* from){
     tnsVectorCopy3d(from->GLocation, to->GLocation);
     tnsVectorCopy3d(from->GRotation, to->GRotation); to->RotationMode=from->RotationMode;
-    to->GScale = from->GScale;
+    tnsVectorCopy3d(from->GScale, to->GScale); 
     tnsGlobalTransformValueChanged(to);
 }
 void tnsRotateObjectLocalValues(tnsObject *o, real x, real y, real z){
@@ -3309,7 +3309,7 @@ void tnsSetObjectPositionLocal(tnsObject*o, real x, real y, real z){
 void tnsResetObjectTransformations(tnsObject* o, int reset_loc,int reset_rot,int reset_sca){
     if(reset_loc){ tnsVectorSet3(o->Location,0,0,0); }
     if(reset_rot){ tnsVectorSet4(o->Rotation,0,0,0,0); }
-    if(reset_sca){ o->Scale=1; }
+    if(reset_sca){ tnsVectorSet3(o->Rotation,1,1,1);  }
     tnsSelfTransformValueChanged(o);
 }
 void tnsMoveObjectLocal(tnsObject *o, real x, real y, real z){
@@ -3408,28 +3408,27 @@ void tnsRotateObjectGlobalForDelta(tnsObject *o, real x, real y, real z, real an
     //memcpy(o->GlobalTransform, res1, sizeof(tnsMatrix44d));
     tnsGlobalMatrixChangedForDelta(o,1);
 }
-void tnsScaleObject(tnsObject *o, real fac, real cx,real cy,real cz){
+void tnsScaleObject(tnsObject *o, real x,real y,real z, real cx,real cy,real cz){
     tnsMatrix44d sca,res1,res2;
-    tnsMakeScaleMatrix44d(sca,fac,fac,fac);
+    tnsMakeScaleMatrix44d(sca,x,y,z);
     tnsMultiply44d(res1,o->GlobalTransform,sca);
     tnsVector3d delta; delta[0]=res1[12]-cx; delta[1]=res1[13]-cy; delta[2]=res1[14]-cz;
     tnsVector3d c; c[0]=cx; c[1]=cy; c[2]=cz;
-    tnsVectorMultiSelf3d(delta, fac);
+    delta[0]*=x; delta[1]*=y; delta[2]*=z;
     tnsVectorPlus3d(&res1[12],c,delta);
     memcpy(o->GlobalTransform, res1, sizeof(tnsMatrix44d));
     tnsGlobalMatrixChanged(o,1);
 }
-void tnsScaleObjectDelta(tnsObject *o, real fac, real cx,real cy,real cz){
+void tnsScaleObjectDelta(tnsObject *o, real x,real y,real z, real cx,real cy,real cz){
     tnsMatrix44d sca,res1,res2;
-    tnsMakeScaleMatrix44d(sca,fac,fac,fac);
-    tnsMultiply44d(res1,o->DeltaTransform,sca);
+    tnsMakeScaleMatrix44d(sca,x,y,z);
+    tnsMultiply44d(res1,o->GlobalTransform,sca);
     tnsVector3d delta; delta[0]=res1[12]-cx; delta[1]=res1[13]-cy; delta[2]=res1[14]-cz;
     tnsVector3d c; c[0]=cx; c[1]=cy; c[2]=cz;
-    tnsVectorMultiSelf3d(delta, fac);
+    delta[0]*=x; delta[1]*=y; delta[2]*=z;
     tnsVectorPlus3d(&res1[12],c,delta);
-    memcpy(o->DeltaTransform, res1, sizeof(tnsMatrix44d));
-    tnsExtractDeltaTransformValue(o);
-    tnsSelfMatrixChanged(o,1);
+    memcpy(o->GlobalTransform, res1, sizeof(tnsMatrix44d));
+    tnsGlobalMatrixChangedForDelta(o,1);
 }
 void tnsZoomViewingCamera(tnsCamera *c, real Ratio){
     if (c->FocusDistance < 0.1) return;

+ 6 - 2
la_tns_mesh.c

@@ -338,9 +338,13 @@ void tnsDrawMeshObjectOutline(tnsEvaluatedInstance* ei, void* unused){
     real* color=(ei->IsActive)?laAccentColor(LA_BT_TEXT):laAccentColor(LA_BT_NORMAL);
     tnsDrawBatch(((tnsMeshObject*)ei->Object)->Batch, "body", color, 0);
 }
-void tnsDrawMeshObject(tnsEvaluatedInstance* ei, void* unused){
+void tnsDrawMeshObject(tnsEvaluatedInstance* ei, la3DObjectDrawExtra* de){
     tnsEnsureMeshBatch(ei->Object); tnsUseNormal(1);
-    if(!tnsDrawBatch(((tnsMeshObject*)ei->Object)->Batch,"mat",0,0)){
+    if(de->DisplayMode==LA_CANVAS_DISPLAY_MATERIAL){
+        if(!tnsDrawBatch(((tnsMeshObject*)ei->Object)->Batch,"mat",0,0)){
+            tnsDrawBatch(((tnsMeshObject*)ei->Object)->Batch,"body",0,0);
+        }
+    }else{
         tnsDrawBatch(((tnsMeshObject*)ei->Object)->Batch,"body",0,0);
     }
     tnsUseNormal(0);

+ 4 - 4
resources/la_modelling.c

@@ -551,8 +551,8 @@ void la_ApplyScale(MTransformData* td, int uix, int uiy){
             MTOrigObject* to=arrElement(td->Originals, i, sizeof(MTOrigObject)); memcpy(to->o->GlobalTransform, to->Global,sizeof(tnsMatrix44d));
             if(to->Discard){ tnsSelfMatrixChanged(to->o,1); continue; }
             if(td->CanvasDeltaMode) tnsGlobalMatrixChangedForDelta(to->o, 0); else tnsGlobalMatrixChanged(to->o, 0);
-            if(td->CanvasDeltaMode) tnsScaleObjectDelta(to->o,s,LA_COLOR3(td->TCenter));
-            else tnsScaleObject(to->o, s, LA_COLOR3(td->TCenter));
+            if(td->CanvasDeltaMode) tnsScaleObjectDelta(to->o,s,s,s,LA_COLOR3(td->TCenter));
+            else tnsScaleObject(to->o, s,s,s, LA_COLOR3(td->TCenter));
         }
     }else{
         tnsVector3d use_delta={s,s,s};
@@ -654,12 +654,12 @@ void la_RestoreTransform(tnsObject* ob, int restore_type, int restore_delta){
     if(restore_delta){
         if(restore_type==LA_TRANSFORM_RESTORE_LOC){ tnsVectorSet3(ob->DLocation,0,0,0); }
         elif(restore_type==LA_TRANSFORM_RESTORE_ROT){ tnsVectorSet3(ob->DRotation,0,0,0); }
-        elif(restore_type==LA_TRANSFORM_RESTORE_SCA){ ob->DScale=1; }
+        elif(restore_type==LA_TRANSFORM_RESTORE_SCA){ tnsVectorSet3(ob->DScale,1,1,1); }
         tnsDeltaTransformValueChanged(ob);
     }else{
         if(restore_type==LA_TRANSFORM_RESTORE_LOC){ tnsVectorSet3(ob->Location,0,0,0); }
         elif(restore_type==LA_TRANSFORM_RESTORE_ROT){ tnsVectorSet3(ob->Rotation,0,0,0); }
-        elif(restore_type==LA_TRANSFORM_RESTORE_SCA){ ob->Scale=1; }
+        elif(restore_type==LA_TRANSFORM_RESTORE_SCA){ tnsVectorSet3(ob->Scale,1,1,1); }
         tnsSelfTransformValueChanged(ob);
     }
 }

+ 1 - 1
resources/la_operators.c

@@ -558,7 +558,7 @@ int OPMOD_UDFRead(laOperator *a, laEvent *e){
                 laFreeOlderDifferences(1);
                 laExtractUDF(upe->UDF, m, upe->Append?LA_UDF_MODE_APPEND:LA_UDF_MODE_OVERWRITE, 0);
                 laCloseUDF(upe->UDF);
-                laRecordEverythingAndPush();
+                laRecordEverythingAndPush(); laNotifyUsers("la.differences");
                 return LA_FINISHED;
             }
         }

+ 15 - 9
resources/la_properties.c

@@ -581,12 +581,12 @@ void *tnsget_FirstChildObject(tnsObject *ob){
     return ob->ChildObjects.pFirst;
 }
 
-void tnsset_ObjectLocation(tnsObject* o, int n, real val){ o->Location[n]=val; tnsSelfTransformValueChanged(o); laNotifyUsers("tns.world"); }
+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"); }
-void tnsset_ObjectScale(tnsObject* o, real val){ o->Scale=val; tnsSelfTransformValueChanged(o); laNotifyUsers("tns.world"); }
+void tnsset_ObjectScale(tnsObject* o, int n, real val){ o->Scale[n]=val; tnsSelfTransformValueChanged(o); laNotifyUsers("tns.world"); }
 void tnsset_ObjectDLocationARR(tnsObject* o, real* arr){ tnsVectorCopy3d(arr,o->DLocation); tnsDeltaTransformValueChanged(o); laNotifyUsers("tns.world"); }
 void tnsset_ObjectDRotationARR(tnsObject* o, real* arr){ tnsVectorCopy3d(arr,o->DRotation); tnsDeltaTransformValueChanged(o); laNotifyUsers("tns.world"); }
-void tnsset_ObjectDScale(tnsObject* o, real val){ o->DScale=val; tnsDeltaTransformValueChanged(o); laNotifyUsers("tns.world"); }
+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; }
 
@@ -805,10 +805,16 @@ void tnspost_Material(tnsMaterial *m){
     //if(m->AsLibrary){ tnsRefreshMaterialLibraries(); return; }
     //tnsEnsureMaterialShader(m,1);
 }
-void tnspost_Object(tnsObject *o){
-    laListItemPointer* NextLip;
+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);
+    }
     for(laListItemPointer* lip=o->ChildObjects.pFirst;lip;lip=NextLip){
-        NextLip=lip->pNext; if(!lip->p){ lstRemoveItem(&o->ChildObjects,lip); memFree(lip); }
+        NextLip=lip->pNext; if(!lip->p){ lstRemoveItem(&o->ChildObjects,lip); memFree(lip); continue; }
+        for(laListItemPointer* lip2=NextLip;lip2;lip2=NextLip2){ NextLip2=lip2->pNext;
+            if(lip2->p==lip->p){ NextLip=lip2->pNext; lstRemoveItem(&o->ChildObjects,lip2); memFree(lip2);  continue; }
+        }
     }
 }
 void tnspropagate_Object(tnsObject* o, laUDF* udf, int force){
@@ -1119,13 +1125,13 @@ void la_RegisterTNSProps(){
         }
         laAddFloatProperty(p, "location", "Location", "XYZ Location In Local Coordinates", 0,"X,Y,Z", 0,0,0,0.1, 0,0,offsetof(tnsObject, Location), 0,0,3, 0,tnsset_ObjectLocation, 0,0,0,0,0,0);
         laAddFloatProperty(p, "rotation", "Rotation", "Rotation In Local Coordinates", 0,"X,Y,Z", 0,0,0,0,0,0,offsetof(tnsObject, Rotation), 0,0,3, 0,tnsset_ObjectRotation, 0,0,0,0,0,0);
-        laAddFloatProperty(p, "scale", "Scale", "Local Uniform Scale", 0,0,0,0,0,0,0,0,offsetof(tnsObject, Scale), 0,tnsset_ObjectScale, 0,0,0,0,0,0,0,0,0);
+        laAddFloatProperty(p, "scale", "Scale", "Local Scale", 0,"X,Y,Z",0,0,0,0,1,0,offsetof(tnsObject, Scale), 0,0,3,0,tnsset_ObjectScale,0,0,0,0,0,0);
         laAddFloatProperty(p, "glocation", "Global Location", "Location in global coordinates", 0,"X,Y,Z", 0,0,0,0.1, 0,0,offsetof(tnsObject, GLocation), 0,0,3, 0,0,0,0,0,0,0,LA_READ_ONLY);
         laAddFloatProperty(p, "grotation", "Global Rotation", "Rotation in global coordinates", 0,"X,Y,Z", 0,0,0,0,0,0,offsetof(tnsObject, GRotation), 0,0,3, 0,0,0,0,0,0,0,LA_READ_ONLY);
-        laAddFloatProperty(p, "gscale", "Global Scale", "Global uniform scale", 0,0,0,0,0,0,0,0,offsetof(tnsObject, GScale), 0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY);
+        laAddFloatProperty(p, "gscale", "Global Scale", "Global scale", 0,"X,Y,Z",0,0,0,0,1,0,offsetof(tnsObject, GScale), 0,0,3,0,0,0,0,0,0,0,LA_READ_ONLY);
         laAddFloatProperty(p, "dlocation", "Delta Location", "XYZ delta transforms", 0,"X,Y,Z", 0,0,0,0.1, 0,0,offsetof(tnsObject, DLocation), 0,0,3,0,0,0,0,tnsset_ObjectDLocationARR,0,0,LA_PROP_KEYABLE);
         laAddFloatProperty(p, "drotation", "Delta Rotation", "Delta rotation", 0,"X,Y,Z", 0,0,0,0,0,0,offsetof(tnsObject, DRotation), 0,0,3,0,0,0,0,tnsset_ObjectDRotationARR,0,0,LA_PROP_KEYABLE|LA_PROP_ROTATION);
-        laAddFloatProperty(p, "dscale", "Delta Scale", "Delta scale", 0,0,0,0,0,0,0,0,offsetof(tnsObject, DScale), 0,tnsset_ObjectDScale,0,0,0,0,0,0,0,0,LA_PROP_KEYABLE);
+        laAddFloatProperty(p, "dscale", "Delta Scale", "Delta scale", 0,"X,Y,Z",0,0,0,0,1,0,offsetof(tnsObject, DScale), 0,0,3,0,0,0,0,tnsset_ObjectDScaleARR,0,0,LA_PROP_KEYABLE);
         laAddFloatProperty(p, "global_mat", "Global Matrix", "Global transformation matrix", 0,0,0,0,0,0,0,0,offsetof(tnsObject, GlobalTransform), 0,0,16, 0,0,0,0,0,0,0,LA_READ_ONLY);
         laAddFloatProperty(p, "local_mat", "Local Matrix", "Local transformation matrix", 0,0,0,0,0,0,0,0,offsetof(tnsObject, SelfTransform), 0,0,16, 0,0,0,0,0,0,0,LA_READ_ONLY);
         ep = laAddEnumProperty(p, "rotation_mode", "Rotation Mode", "Rotation Mode Of This Object(e.g. XYZ/XZY/Quaternion...)", 0,0,0,0,0,offsetof(tnsObject, RotationMode), 0,0,0,0,0,0,0,0,0,0);{

+ 2 - 2
resources/la_templates.c

@@ -1889,11 +1889,11 @@ void tnsui_BaseObjectProperties(laUiList *uil, laPropPack *This, laPropPack *UNU
         laSplitColumn(gu,gc,0.5); gcl=laLeftColumn(gc,0); gcr=laRightColumn(gc,0);
         laShowLabel(gu,gcl,"Location",0,0); laShowItem(gu,gcl,This,"location")->Flags|=LA_UI_FLAGS_TRANSPOSE;
         laShowLabel(gu,gcr,"Rotation",0,0); laShowItem(gu,gcr,This,"rotation")->Flags|=LA_UI_FLAGS_TRANSPOSE;
-        laShowLabel(gu,gcl,"Scale",0,0);    laShowItem(gu,gcr,This,"scale");
+        laShowLabel(gu,gcr,"Scale",0,0);    laShowItem(gu,gcr,This,"scale")->Flags|=LA_UI_FLAGS_TRANSPOSE;
         laUiItem* b=laOnConditionToggle(gu,gc,0,0,0,0,0);{ strSafeSet(&b->ExtraInstructions,"text=Delta");
             laShowLabel(gu,gcl,"Delta Loc",0,0); laShowItem(gu,gcl,This,"dlocation")->Flags|=LA_UI_FLAGS_TRANSPOSE;
             laShowLabel(gu,gcr,"Delta Rot",0,0); laShowItem(gu,gcr,This,"drotation")->Flags|=LA_UI_FLAGS_TRANSPOSE;
-            laShowLabel(gu,gcl,"Delta Scale",0,0);laShowItem(gu,gcr,This,"dscale");
+            laShowLabel(gu,gcr,"Delta Scale",0,0);laShowItem(gu,gcr,This,"dscale")->Flags|=LA_UI_FLAGS_TRANSPOSE;
         }laEndCondition(gu,b);
         laShowSeparator(gu,gc);
     }laEndCondition(gu,b1);

+ 2 - 2
resources/la_tns_shaders.cpp

@@ -643,7 +643,7 @@ flat out vec3 fNormal;
 out vec3 fGPos;
 void main(){
 	vec4 pos=mProjection * mView * mModel * vVertex;
-	if(DoOffset>0){ pos.xyw*=1.00005; }
+	if(DoOffset!=0){ pos.xyw*=1.0+0.00005*float(DoOffset); }
     gl_Position = pos;
     fColor = vColor;
     fUV=vUV;
@@ -966,7 +966,7 @@ uniform int DoOffset;
 flat out vec3 fIdColor;
 void main(){
 	vec4 pos = mProjection * mView * mModel * vVertex;
-	if(DoOffset>0){ pos.xyw*=1.00005; }
+	if(DoOffset!=0){ pos.xyw*=1.00005; }
     gl_Position = pos;
     fIdColor = vColor;
 })";

+ 13 - 6
resources/la_widgets_viewers.c

@@ -150,6 +150,9 @@ void la_RootObjectDraw(laBoxedTheme *bt, tnsObject *root, laUiItem* ui){
 
     laListHandle xrays={0};
 
+    la3DObjectDrawExtra de={0};
+    de.MeshEditType=e->SelectMode; de.DisplayMode=e->AsPlayer?LA_CANVAS_DISPLAY_MATERIAL:e->DisplayMode;
+
     if(root){
         if(!e->AsPlayer){
             tnsSetObjectTreeEvaluationArgs(root,root->Active,1,1);
@@ -160,10 +163,10 @@ void la_RootObjectDraw(laBoxedTheme *bt, tnsObject *root, laUiItem* ui){
 
         tnsUseShader(T->immShader); tnsEnableShaderv(T->immShader); tnsUseNoTexture();
         tnsUnbindTexture(); tnsUniformUseTexture(T->immShader,0,0); tnsUseMultiplyColor(0);
-        tnsDrawObjectTree(root,TNS_EVAL_LAYER_SOLID,0,e->AsPlayer);
+        tnsDrawObjectTree(root,TNS_EVAL_LAYER_SOLID,&de,e->AsPlayer);
         
-        glLineWidth(3); 
-        tnsUniformUseOffset(T->immShader,1);
+        glLineWidth(7); 
+        tnsUniformUseOffset(T->immShader,-100);
         glDepthMask(GL_FALSE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
         tnsDrawObjectTree(root,TNS_EVAL_LAYER_OUTLINE,0,e->AsPlayer);
         glDepthMask(GL_TRUE); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -179,8 +182,6 @@ void la_RootObjectDraw(laBoxedTheme *bt, tnsObject *root, laUiItem* ui){
         tnsFlush();
     }
 
-    la3DObjectDrawExtra de={0}; de.MeshEditType=e->SelectMode;
-
     if(e->SelectThrough){ glClear(GL_DEPTH_BUFFER_BIT); }
     tnsDrawObjectTree(root,TNS_EVAL_LAYER_OVERLAY,&de,e->AsPlayer);
 
@@ -539,6 +540,7 @@ void laDefault3DViewOverlay(laUiItem *ui){
 
     laShowSeparator(uil,c)->Expand=1;
 
+    laShowItem(uil,c,&ui->ExtraPP,"display_mode")->Flags|=LA_UI_FLAGS_EXPAND;
     laShowItem(uil,c,&ui->ExtraPP,"delta_mode")->Flags|=LA_UI_FLAGS_CYCLE|LA_UI_FLAGS_HIGHLIGHT;
     laShowItem(uil,c,&ui->ExtraPP,"show_details")->Flags|=LA_UI_FLAGS_ICON;
 
@@ -566,7 +568,8 @@ void laDefault3DViewOverlay(laUiItem *ui){
                         laShowLabel(gu, gc, "Loc:", 0, 0);laShowItem(gu, gc, &ui->PP, "active.location")->Flags|=LA_UI_FLAGS_TRANSPOSE;
                         laShowSeparator(gu,gc);
                         laShowLabel(gu, gc, "Rot:", 0, 0);laShowItem(gu, gc, &ui->PP, "active.rotation")->Flags|=LA_UI_FLAGS_TRANSPOSE;
-                        laShowItem(gu, gc, &ui->PP, "active.scale");
+                        laShowSeparator(gu,gc);
+                        laShowLabel(gu, gc, "Sca:", 0, 0);laShowItem(gu, gc, &ui->PP, "active.scale")->Flags|=LA_UI_FLAGS_TRANSPOSE;
                     }laEndCondition(gu,b);
                 }laElse(gu,b1);{
                     laShowLabel(gu, gc, "No active object.", 0, 0);
@@ -1085,6 +1088,10 @@ void la_RegisterUiTypesViewerWidgets(){
             laAddEnumItem(p, "HIDDEN", "Hidden", "Current Axis Is Hidden", U'🛈');
             laAddEnumItem(p, "SHOWN", "Shown", "Current Axis Is Shown", U'i');
         }
+        p = laAddEnumProperty(pc, "display_mode", "Display Mode", "Display mode of the viewport", 0, 0, 0, 0, 0, offsetof(laCanvasExtra, DisplayMode), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);{
+            laAddEnumItemAs(p, "SOLID", "Solid", "Solid object view",LA_CANVAS_DISPLAY_SOLID, 0);
+            laAddEnumItemAs(p, "MATERIAL", "Material", "Material view",LA_CANVAS_DISPLAY_MATERIAL, 0);
+        }
         laAddIntProperty(pc, "height_coeff", "Ui Height", "Ui Height Coefficiency Entry", 0, 0, "Rows", 100, -100, 1, 0, 0, offsetof(laCanvasExtra, HeightCoeff), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
         laAddOperatorProperty(pc, "zoom", "Zoom", "Zoom Viewing Camera", "LA_3d_view_camera_zoom", U'🔎', 0);
         laAddOperatorProperty(pc, "rotate", "Rotate", "Rotate Viewing Camera", "LA_3d_view_camera_rotate", U'🗘', 0);