*/}}
Browse Source

Widget improvements, basic airfoil Cl table

Yiming Wu 2 years ago
parent
commit
aeef7978ea

+ 2 - 1
source/lagui/la_data.c

@@ -718,6 +718,8 @@ laProp *la_CreateProperty(laPropContainer *Container, int Type, const char *Iden
     p->UDFIgnore = (Tag & LA_UDF_IGNORE) ? 1 : 0;
     p->UDFOnly = (Tag & LA_UDF_ONLY) ? 1 : 0;
     p->ReadOnly = (Tag & LA_READ_ONLY) ? 1 : 0;
+    p->IsRadAngle = (Tag & LA_RAD_ANGLE)? 1 : 0;
+    if(p->IsRadAngle&&(!p->Unit)) p->Unit="°"; 
 
     return p;
 }
@@ -730,7 +732,6 @@ laProp *la_MakeDetachedProp(laPanel* p, const char *From, const char *Rename){
     laEnumProp *ep;
     laSubProp *sp;
 
-
     laPropPack TempPP = {0};
     int result = 0;
 

+ 2 - 1
source/lagui/la_data.h

@@ -190,6 +190,7 @@ STRUCTURE(laProp){
     char UDFIgnore;
     char UDFOnly;
     char UDFIsSingle;
+    char IsRadAngle;
 
     //int           SignalThrow;
     //int           SignalCatch;
@@ -635,7 +636,7 @@ STRUCTURE(laDiffPost){
 #define LA_UDF_VARIABLE_NODE_SIZE (1<<18)
 #define LA_UDF_FIXED_NODE_SIZE (1<<19)
 #define LA_UDF_LOCAL (1<<20)
-#define LA_UDF_IS_RAD (1<<21)
+#define LA_RAD_ANGLE (1<<21)
 #define LA_UDF_PRINT_STATICS (1<<22)
 #define LA_UDF_NUID_SEEK (1<<23)
 #define LA_UDF_NUID_LINK_FILES (1<<24)

+ 6 - 0
source/lagui/la_interface.h

@@ -752,6 +752,8 @@ STRUCTURE(laCanvasTemplate){
 #define LA_CANVAS_CURSOR_CROSS 1
 #define LA_CANVAS_CURSOR_BOX   2
 #define LA_CANVAS_CURSOR_ARROW 3
+#define LA_CANVAS_CURSOR_X     4
+#define LA_CANVAS_CURSOR_Y     5
 
 #define LA_CANVAS_SELECT_MODE_VERTS 0
 #define LA_CANVAS_SELECT_MODE_EDGES 1
@@ -760,6 +762,10 @@ STRUCTURE(laCanvasTemplate){
 #define LA_CANVAS_SELECT_THROUGH_OFF 0
 #define LA_CANVAS_SELECT_THROUGH_ON  1
 
+void la_CanvasDrawOverlay(laUiItem *ui, int h);
+void la_CanvasInit(laUiItem *ui);
+void la_CanvasDestroy(laUiItem *ui);
+
 STRUCTURE(laCanvasExtra){
     laListItem Item;
     tnsOffscreen *OffScr;

+ 27 - 26
source/lagui/la_kernel.c

@@ -843,11 +843,11 @@ int la_SetUpUiListMatrix(laUiListDraw *uild, laUiList *Target, int _L, int _R, i
         return 0;
     }
 
-    tnsViewportWithScissor(uildi->L, PanelH - uildi->B, uildi->R - uildi->L, uildi->B - uildi->U);
-    tnsOrtho(Target->L + Target->PanX + uildi->DifX,
-             Target->L + Target->PanX + uildi->DifX + (uildi->R - uildi->L),
-             Target->U + Target->PanY + uildi->DifY + (uildi->B - uildi->U),
-             Target->U + Target->PanY + uildi->DifY,
+    tnsViewportWithScissor(uildi->L-1, PanelH - uildi->B-1, uildi->R - uildi->L+2, uildi->B - uildi->U+2);
+    tnsOrtho(Target->L + Target->PanX + uildi->DifX -1,
+             Target->L + Target->PanX + uildi->DifX +1+ (uildi->R - uildi->L),
+             Target->U + Target->PanY + uildi->DifY +1+ (uildi->B - uildi->U),
+             Target->U + Target->PanY + uildi->DifY -1,
              -100, 100);
 
     lstPushItem(&uild->Items, uildi);
@@ -895,11 +895,11 @@ void la_SetUpUiListMatrixInLine(laUiListDraw *uild, int L, int R, int U, int B,
 void la_RebuildCurrentUiListMatrix(laUiListDraw *uild, laUiList *Target, int LimH, int PanelH){
     laUiListDrawItem *uildi = uild->Items.pFirst;
 
-    tnsViewportWithScissor(uildi->L, PanelH - uildi->B, uildi->R - uildi->L, uildi->B - uildi->U);
-    tnsOrtho(Target->L + Target->PanX + uildi->DifX,
-             Target->L + Target->PanX + uildi->DifX + (uildi->R - uildi->L),
-             Target->U + Target->PanY + uildi->DifY + (uildi->B - uildi->U),
-             Target->U + Target->PanY + uildi->DifY,
+    tnsViewportWithScissor(uildi->L-1, PanelH - uildi->B-1, uildi->R - uildi->L+2, uildi->B - uildi->U+2);
+    tnsOrtho(Target->L + Target->PanX + uildi->DifX -1,
+             Target->L + Target->PanX + uildi->DifX +1 + (uildi->R - uildi->L),
+             Target->U + Target->PanY + uildi->DifY +1 + (uildi->B - uildi->U),
+             Target->U + Target->PanY + uildi->DifY -1,
              -100, 100);
 }
 void la_RestoreLastUiListMatrix(laUiListDraw *uild, int PanelH){
@@ -916,11 +916,11 @@ void la_RestoreLastUiListMatrix(laUiListDraw *uild, int PanelH){
 
     Target = uildi->Target;
 
-    tnsViewportWithScissor(uildi->L, PanelH - uildi->B, uildi->R - uildi->L, uildi->B - uildi->U);
-    tnsOrtho(Target->L + Target->PanX + uildi->DifX,
-             Target->L + Target->PanX + uildi->DifX + (uildi->R - uildi->L),
-             Target->U + Target->PanY + uildi->DifY + (uildi->B - uildi->U),
-             Target->U + Target->PanY + uildi->DifY,
+    tnsViewportWithScissor(uildi->L-1, PanelH - uildi->B-1, uildi->R - uildi->L+2, uildi->B - uildi->U+2);
+    tnsOrtho(Target->L + Target->PanX + uildi->DifX -1,
+             Target->L + Target->PanX + uildi->DifX +1 + (uildi->R - uildi->L),
+             Target->U + Target->PanY + uildi->DifY +1 + (uildi->B - uildi->U),
+             Target->U + Target->PanY + uildi->DifY -1,
              -100, 100);
 }
 void la_SetupUiListLimitMatrix(laUiListDraw *uild, int L, int R, int U, int B, int PanelH){
@@ -3917,6 +3917,7 @@ int la_ResetUiColum(laColumn *c, laColumn *Top, int U, int L, int R, int LR, int
     int rep;
     int sp;
     int rev;
+    int M=_LA_THEME_PANEL->LM+_LA_THEME_PANEL->RM;
 
     if (!c) return 0;
 
@@ -3930,8 +3931,8 @@ int la_ResetUiColum(laColumn *c, laColumn *Top, int U, int L, int R, int LR, int
         c->IR = sp;
         if (repos){
             c->IR = repos;
-        }else if (c->MaxW*LA_RH && c->IR - c->IL > c->MaxW*LA_RH){
-            c->IR = c->IL + c->MaxW*LA_RH;
+        }else if (c->MaxW*LA_RH && c->IR - c->IL > c->MaxW*LA_RH+M){
+            c->IR = c->IL + c->MaxW*LA_RH+M;
             rev = c->IR;
         }
     }else if (LR == 2){
@@ -3939,8 +3940,8 @@ int la_ResetUiColum(laColumn *c, laColumn *Top, int U, int L, int R, int LR, int
         c->IR = R;
         if (repos){
             c->IL = repos;
-        }else if (c->MaxW*LA_RH && c->IR - c->IL > c->MaxW*LA_RH){
-            c->IL = c->IR - c->MaxW*LA_RH;
+        }else if (c->MaxW*LA_RH && c->IR - c->IL > c->MaxW*LA_RH+M){
+            c->IL = c->IR - c->MaxW*LA_RH-M;
             rev = c->IL;
         }
     }else if (LR == 0){
@@ -4302,12 +4303,12 @@ int la_UpdateUiListRecursive(laUiList *uil, int U, int L, int R, int B, int Fast
                             la_AddInstancePage(ui, TInstance, 0);
                             la_CalcUiTopInfluence(&uil->Columns, ui);
                             if (Template) laMakeUiListFromTemplate(ui->Page, Template, &ParentPanel->PP, &ParentPanel->PropLinkPP, &ui->PP, 0, &uil->Columns, ui->TemplateContext);
-                            SubB = la_UpdateUiListRecursive(ui->Page, Gap+Begin+(NoDecal?0:bt->TM), EL+(NoDecal?0:bt->LM), ER-(NoDecal?0:bt->RM), B, Fast, ParentPanel) + bt->TM;
+                            SubB = la_UpdateUiListRecursive(ui->Page, Gap+Begin+(NoDecal?0:bt->TM), EL+(NoDecal?0:bt->LM), ER-(NoDecal?0:bt->RM), B, Fast, ParentPanel) +(NoDecal?0:bt->TM);
                             ElementB = RowPriority ? (SubB > ElementB ? SubB : ElementB) : SubB;
                             iuil = ui->Page->Item.pNext;
                     }else{
                         la_CalcUiTopInfluence(&uil->Columns, ui);
-                        SubB = la_UpdateUiListRecursive(iuil, Gap+Begin+(NoDecal?0:bt->TM), EL+(NoDecal?0:bt->LM), ER-(NoDecal?0:bt->RM), B, Fast, ParentPanel) + bt->TM;
+                        SubB = la_UpdateUiListRecursive(iuil, Gap+Begin+(NoDecal?0:bt->TM), EL+(NoDecal?0:bt->LM), ER-(NoDecal?0:bt->RM), B, Fast, ParentPanel) + (NoDecal?0:bt->TM);
                         ElementB = RowPriority ? (SubB > ElementB ? SubB : ElementB) : SubB;
                         la_CalcUiItemInfluence(&uil->Columns, ui);
                         iuil = iuil->Item.pNext;
@@ -4358,7 +4359,7 @@ int la_UpdateUiListRecursive(laUiList *uil, int U, int L, int R, int B, int Fast
                     la_CalcUiTopInfluence(&uil->Columns, ui);
                     laMakeUiListFromTemplate(ui->Page, Template, &ParentPanel->PP, &ParentPanel->PropLinkPP, &ui->PP, 0, &uil->Columns, ui->TemplateContext);
                     SubB = la_UpdateUiListRecursive(ui->Page, ui->TB+(NoDecal?0:bt->TM), ui->TL+(NoDecal?0:bt->LM), ui->TR-(NoDecal?0:bt->RM), B, Fast, ParentPanel);
-                    ui->TB = SubB + bt->BM;
+                    ui->TB = SubB + (NoDecal?0:bt->TM);
                 }else if (ui->Subs.pFirst){
                     if (!TInstance || TInstance != ui->Page->Instance){
                         la_DestroyTabPage(ui, ui->Subs.pFirst, 0);
@@ -4368,12 +4369,12 @@ int la_UpdateUiListRecursive(laUiList *uil, int U, int L, int R, int B, int Fast
                             la_CalcUiTopInfluence(&uil->Columns, ui);
                             laMakeUiListFromTemplate(ui->Page, Template, &ParentPanel->PP, &ParentPanel->PropLinkPP, &ui->PP, 0, &uil->Columns, ui->TemplateContext);
                             SubB = la_UpdateUiListRecursive(ui->Page, ui->TB+(NoDecal?0:bt->TM), ui->TL+(NoDecal?0:bt->LM), ui->TR-(NoDecal?0:bt->RM), B, Fast, ParentPanel);
-                            ui->TB = SubB + bt->BM;
+                            ui->TB = SubB + (NoDecal?0:bt->TM);
                         }else
                             ui->TB = ui->TU + LA_RH + bt->BM;
                     }else{
                         SubB = la_UpdateUiListRecursive(ui->Page, ui->TB+(NoDecal?0:bt->TM), ui->TL+(NoDecal?0:bt->LM), ui->TR-(NoDecal?0:bt->RM), B, Fast, ParentPanel);
-                        ui->TB = SubB + bt->BM;
+                        ui->TB = SubB + (NoDecal?0:bt->TM);
                     }
                 }
                 if (ui->TB-ui->TU<LA_RH) ui->TB = ui->TU + LA_RH;
@@ -4392,7 +4393,7 @@ int la_UpdateUiListRecursive(laUiList *uil, int U, int L, int R, int B, int Fast
                     SubB = la_UpdateUiListRecursive(ui->Page,
                         ui->TB + (ui->State == LA_UI_ACTIVE ? 0 : LA_RH)+(NoDecal?0:bt->TM), ui->TL+(NoDecal?0:bt->LM), ui->TR-(NoDecal?0:bt->RM)-scrollw, B, Fast, ParentPanel);
                     ui->TB = (ui->Page->HeightCoeff > 0 ? ui->TU + ui->Page->HeightCoeff * LA_RH :
-                            (ui->Page->HeightCoeff < 0 ? B + (ui->Page->HeightCoeff+1) * LA_RH : SubB)) + bt->BM;
+                            (ui->Page->HeightCoeff < 0 ? B + (ui->Page->HeightCoeff+1) * LA_RH : SubB)) + (NoDecal?0:bt->TM);
                     int subh = ui->TB-ui->TU-LA_RH-bt->TM-bt->BM;
                     if((ui->Page->TR>ui->TR-(NoDecal?0:bt->RM) && (!ui->Page->ScrollerShownH)) ||
                         (ui->Page->TR<=ui->TR-(NoDecal?0:bt->RM)  && ui->Page->ScrollerShownH)){
@@ -4913,7 +4914,7 @@ int la_DrawUiListRecursive(laUiListDraw *uild, laUiList *uil, int L, int R, int
                 if(!(ui->Flags&LA_UI_FLAGS_NO_OVERLAY)){
                     for (sub = ui->Subs.pFirst; sub; sub = sub->Item.pNext){
                         tnsFlush();
-                        Ret += la_DrawUiListRecursive(uild, sub, L, R, U, B, 10000, ConditionStackLevel, GlobalX, GlobalY, RegisterNodes);
+                        Ret += la_DrawUiListRecursive(uild, sub, L-1, R+1, U-1, B+1, 10000, ConditionStackLevel, GlobalX, GlobalY, RegisterNodes);
                     }
                 }
             }

+ 20 - 10
source/lagui/la_tns.h

@@ -79,16 +79,16 @@ struct _tnsCommand
     GLenum Shade;    //0-falt 1-smooth
     GLfloat UniformColor[4];
 
-    short NumVert;
-    short NumIndex;
-    short VertBegin;
-    short VertEnd; //'END'is the next one after the last one.
-    short ColorBegin;
-    short ColorEnd;
-    short TexCoordBegin;
-    short TexCoordEnd;
-    short NormalBegin;
-    short NormalEnd;
+    int NumVert;
+    int NumIndex;
+    int VertBegin;
+    int VertEnd; //'END'is the next one after the last one.
+    int ColorBegin;
+    int ColorEnd;
+    int TexCoordBegin;
+    int TexCoordEnd;
+    int NormalBegin;
+    int NormalEnd;
     GLushort IndexBegin;
     GLushort IndexEnd;
 
@@ -566,6 +566,9 @@ STRUCTURE(tnsMakeTransformNode){
 
 NEED_STRUCTURE(tnsBatch)
 
+#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
 
@@ -1036,6 +1039,8 @@ void tnsPrintMatrix44d(tnsMatrix44d l);
 
 int tnsPointInsideTriangle3d(tnsVector3d v, tnsVector3d v0, tnsVector3d v1, tnsVector3d v2);
 
+int tnsIntersectPlaneRay(tnsVector3d n, tnsVector3d p0, tnsVector3d l0, tnsVector3d l, real* t);
+
 void tnsExtractXYZEuler44d(tnsMatrix44d mat, real *x_result, real *y_result, real *z_result);
 void tnsExtractLocation44d(tnsMatrix44d mat, real *x_result, real *y_result, real *z_result);
 void tnsExtractUniformScale44d(tnsMatrix44d mat, real *result);
@@ -1149,6 +1154,7 @@ void tnsDrawMeshObject(tnsMeshObject* mo, int DrawAsObjectSelection, int MeshSel
 
 void la_RegisterModellingOperators();
 
+void tnsGetCameraProjection(tnsMatrix44d* mat, int w, int h, tnsCamera* Camera);
 void tnsGetCameraViewProjection(tnsMatrix44d* mat, int w, int h, tnsCamera* Camera);
 void tnsApplyCameraView(int W, int H, tnsCamera *Camera);
 void tnsApplyShadowCameraView(tnsLight *Light);
@@ -1159,6 +1165,8 @@ void tnsLookAt(tnsObject *o, tnsVector3d Target, tnsVector3d Up);
 
 void tnsDrawThisObject(tnsObject *o, tnsObject *active, int DrawAsObjectSelection, int MeshSelectionMode);
 void tnsDrawObjectTree(tnsObject *from, tnsObject *active, int DrawAsObjectSelection, int MeshSelectionMode);
+void tnsDrawObjectOrigins(tnsObject *from, tnsObject *active, int AllOrigins);
+void tnsDrawCursor(tnsObject* root);
 void tnsDrawScene(int W, int H, tnsObject *root);
 void tnsDrawWorld(int W, int H);
 
@@ -1296,6 +1304,8 @@ void tnsMakeLinerGradient4dv(real *arr, int num_points, real *rgb0, real *rgb1);
 
 void tnsMakeFoucsSquare(int L, int R, int U, int B, int W);
 void tnsDrawFloor(int Size, int Span, int *ShowAxis);
+void tnsDraw2DGrid10(real L, real R, real U, real B, real xmin, real xmax, real ymin, real ymax, real MostDenseW, real MostDenseH,
+                     real* color4, real AlphaFactor, int ShowGrid, int TextAlign);
 
 void tnsMakeIndexUInt(unsigned int *result, int num, ...);
 void tnsMakeBridgedIndex(unsigned int *result, int num, int revert, int begin);

+ 103 - 16
source/lagui/la_tns_kernel.c

@@ -646,7 +646,7 @@ int tnsEnableShader(int index){
     tmsi = tKnlGetCurrentMatStackItem();
     tnsShaderApplyProjection(tns, tmsi->projection);
     tnsShaderApplyView(tns, tmsi->view);
-    tnsShaderApplyModel(tns, tmsi->model);
+    tnsShaderApplyModel(tns, tmsi->model); tnsUseShader(tns);
     return 1;
 }
 int tnsEnableShaderv(tnsShader *shader){
@@ -666,7 +666,7 @@ int tnsEnableShaderv(tnsShader *shader){
     tnsShaderApplyProjection(tns, tmsi->projection);
     tnsShaderApplyProjectionInverse(tns, tmsi->projection);
     tnsShaderApplyView(tns, tmsi->view);
-    tnsShaderApplyModel(tns, tmsi->model);
+    tnsShaderApplyModel(tns, tmsi->model); tnsUseShader(tns);
 
     //if (tns->iVertex != -1) glEnableVertexAttribArray(tns->iVertex);
     //if (tns->iColor != -1) glEnableVertexAttribArray(tns->iColor);
@@ -1329,6 +1329,16 @@ void tnsMakeViewportMatrix44d(tnsMatrix44d m, real w, real h, real Far, real Nea
     //m[15] = 1;
 }
 
+int tnsIntersectPlaneRay(tnsVector3d n, tnsVector3d p0, tnsVector3d l0, tnsVector3d l, real* t){
+    float denom = tnsDot3d(n, l, 0);
+    if (denom > 1e-6){
+        tnsVector3d p0l0; tnsVectorMinus3d(p0l0,p0 ,l0);
+        (*t) = tnsDot3d(p0l0, n, 0) / denom;
+        return ((*t) >= 0);
+    }
+    return 0;
+}
+
 void tnsInitFirstLevel(tnsMatrixStack *tms){
     tnsLoadIdentity44d(tms->level[0].model);
     tnsLoadIdentity44d(tms->level[0].projection);
@@ -2132,7 +2142,7 @@ void tnsShadeMode(GLenum ShadeMode){
 }
 void tnsVertex3d(real x, real y, real z){
     tnsCommand *c = &T->DrawingCommand[T->NextCommand];
-    short vend = c->VertEnd;
+    int vend = c->VertEnd;
 
     c->UseVert = 1;
 
@@ -2161,7 +2171,7 @@ void tnsVertex3d(real x, real y, real z){
 }
 void tnsVertex2d(real x, real y){
     tnsCommand *c = &T->DrawingCommand[T->NextCommand];
-    short vend = c->VertEnd;
+    int vend = c->VertEnd;
 
     c->UseVert = 1;
 
@@ -2186,7 +2196,7 @@ void tnsVertex2d(real x, real y){
 void tnsVertexArray2d(real *verts, int amount){
     tnsCommand *c = &T->DrawingCommand[T->NextCommand];
     int trans = 2 * amount;
-    short vend = c->VertEnd;
+    int vend = c->VertEnd;
 
     c->UseVert = 1;
 
@@ -2213,7 +2223,7 @@ void tnsVertexArray2d(real *verts, int amount){
 void tnsVertexArray3d(real *verts, int amount){
     tnsCommand *c = &T->DrawingCommand[T->NextCommand];
     int trans = 3 * amount;
-    short vend = c->VertEnd;
+    int vend = c->VertEnd;
 
     c->UseVert = 1;
 
@@ -3556,6 +3566,10 @@ void tnsSelectObject(tnsObject* o, int Select, int Toggle){
     elif(Select) o->Flags|=TNS_OBJECT_FLAGS_SELECTED; else o->Flags&=(~TNS_OBJECT_FLAGS_SELECTED);
 }
 
+void tnsGetCameraProjection(tnsMatrix44d* mat, int w, int h, tnsCamera* Camera){
+    tnsMatrix44d inv, result;
+    tnsMakePerspectiveMatrix44d(mat, Camera->FOV, (real)w / (real)h, Camera->ZMin, Camera->ZMax);
+}
 void tnsGetCameraViewProjection(tnsMatrix44d* mat, int w, int h, tnsCamera* Camera){
     tnsMatrix44d inv, result;
     tnsMakePerspectiveMatrix44d(mat, Camera->FOV, (real)w / (real)h, Camera->ZMin, Camera->ZMax);
@@ -3674,6 +3688,25 @@ void tnsDrawCamera(tnsObject *o){
     tnsPackAs(GL_LINE_STRIP);
     tnsFlush();
 }
+void tnsDrawCross(real x,real y,real z,real x1,real x2,real y1,real y2,real z1,real z2){
+    tnsVertex3d(x+x1, y+0.0, z+0.0); tnsVertex3d(x+x2, y+0.0, z+0.0);
+    tnsVertex3d(x+0.0,y+ y1, z+0.0); tnsVertex3d(x+0.0,y+ y2, z+0.0);
+    tnsVertex3d(x+0.0,y+ 0.0,z+ z1); tnsVertex3d(x+0.0,y+ 0.0,z+ z2);
+}
+void tnsDrawPlaceholder(tnsObject* o, tnsObject *active, int DrawAsSelection){
+    if(T->BindedShader==T->SelectionShader){
+        int i=o->SelectID; real color[4]={0,0,0,1}; TNS_ID_TO_COLOR(color,i); tnsColor4dv(color);
+    }else{
+        if(DrawAsSelection && (!(o->Flags&TNS_OBJECT_FLAGS_SELECTED))) return;
+        if(!DrawAsSelection && (o->Flags&TNS_OBJECT_FLAGS_SELECTED)) return;
+        if(o==active){ tnsColor4dv(laAccentColor(LA_BT_TEXT_ACTIVE)); }
+        elif(o->Flags&TNS_OBJECT_FLAGS_SELECTED){ tnsColor4dv(laAccentColor(LA_BT_NORMAL)); }
+        else tnsColor4dv(laThemeColor(_LA_THEME_3D_VIEW,LA_BT_BORDER));
+    }
+    tnsDrawCross(0,0,0,-1,5,-1,5,-1,5);
+    tnsPackAs(GL_LINES);
+    tnsFlush();
+}
 void tnsDrawThisObject(tnsObject *o,tnsObject *active, int DrawAsObjectSelection, int MeshSelectionMode){
     if (!o->Show) return;
     switch (o->Type){
@@ -3685,16 +3718,7 @@ void tnsDrawThisObject(tnsObject *o,tnsObject *active, int DrawAsObjectSelection
         break;
     case TNS_OBJECT_EMPTY:
     default:
-        ////if (T->CurrentShader != T->uiShader) tnsEnableShaderv(T->uiShader);
-        //tnsVertex3d(-1.0, 0.0, 0.0);
-        //tnsVertex3d(5.0, 0.0, 0.0);
-        //tnsVertex3d(0.0, 5.0, 0.0);
-        //tnsVertex3d(0.0, -1.0, 0.0);
-        //tnsVertex3d(0.0, 0.0, -1.0);
-        //tnsVertex3d(0.0, 0.0, 5.0);
-        //tnsColor4d(1, 1, 1, 1);
-        //tnsPackAs(GL_LINES);
-        //tnsFlush();
+        tnsDrawPlaceholder(o,active,DrawAsObjectSelection);
         break;
     }
 }
@@ -3710,6 +3734,33 @@ void tnsDrawObjectTree(tnsObject *from, tnsObject *active, int DrawAsObjectSelec
         tnsPopMatrix();
     }
 }
+void tnsDrawObjectOrigins(tnsObject *from, tnsObject *active, int AllOrigins){
+    tnsObject *o; if(!from) return;
+    tnsVector4d pos;
+    for (laListItemPointer* lip=from->ChildObjects.pFirst;lip;lip=lip->pNext){
+        o=lip->p; if((!AllOrigins) && (o!=active) && (!(o->Flags&TNS_OBJECT_FLAGS_SELECTED))) continue;
+        if(o->Type==TNS_OBJECT_MESH && ((tnsMeshObject*)o)->Mode==TNS_MESH_EDIT_MODE){ continue; }
+        if(T->BindedShader==T->SelectionShader){  int i=o->SelectID; real color[4]={0,0,0,1}; TNS_ID_TO_COLOR(color,i); tnsColor4dv(color); }
+        else{
+            if(o==active){ tnsColor4dv(laAccentColor(LA_BT_TEXT_ACTIVE)); }
+            elif(o->Flags&TNS_OBJECT_FLAGS_SELECTED){ tnsColor4dv(laAccentColor(LA_BT_NORMAL)); }
+            else{ real* c=laThemeColor(_LA_THEME_3D_VIEW,LA_BT_BORDER); tnsColor4d(LA_COLOR3(c),0.5); }
+        }
+        tnsVertex3d(LA_COLOR3(o->GLocation)); tnsPackAs(GL_POINTS);
+    }
+}
+void tnsDrawCursor(tnsObject* root){
+    if(root->Type!=TNS_OBJECT_ROOT) return;
+    tnsMatrix44d vp; tnsVector4d t; tnsVector4d t1={0,0,0,1};
+    tnsMultiply44d(vp,tnsGetProjectionMatrix(),tnsGetViewMatrix());
+    tnsApplyTransform44d(t,vp,root->GLocation); real w=t[3]*0.05;
+    tnsDrawCross(LA_COLOR3(root->GLocation),-w,w,-w,w,-w,w); tnsColor4d(0,0,0,0.5);
+    tnsPackAs(GL_LINES); glLineWidth(5);
+    tnsFlush(); w*=0.9;
+    tnsDrawCross(LA_COLOR3(root->GLocation),-w,w,-w,w,-w,w); tnsColor4dv(laThemeColor(_LA_THEME_3D_VIEW,LA_BT_BORDER));
+    tnsPackAs(GL_LINES); glLineWidth(2);
+    tnsFlush(); glLineWidth(1);
+}
 
 //===================================================================[Material]
 
@@ -4175,3 +4226,39 @@ void tnsDrawFloor(int Size, int Span, int *ShowAxis){
         tnsPackAs(GL_LINES);
     }
 }
+
+void tnsDraw2DGrid10(real L, real R, real U, real B, real xmin, real xmax, real ymin, real ymax, real MostDenseW, real MostDenseH,
+                     real* color4, real AlphaFactor, int ShowGrid, int TextAlign){
+    real span; real W=R-L, H=B-U, rangeX=xmax-xmin, rangeY=ymax-ymin, dW=rangeX/W, dH=rangeY/H;
+    real MinSpanW=fabs(MostDenseW*dW), MinSpanH=fabs(MostDenseH*dH);
+    
+    for(int i=0;i<20;i++){ span=1e-5*pow(10,i); if(span>MinSpanW) break; }
+    real startx=((real)((int)(xmin/span)))*span; real x=startx;
+    while(x<xmax){
+        real lx=tnsInterpolate(L,R,tnsGetRatiod(xmin,xmax,x));
+        tnsVertex2d(lx,U);tnsVertex2d(lx,B); x+=span;
+    } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor*AlphaFactor*AlphaFactor); tnsPackAs(GL_LINES);
+    x=startx; while(x<xmax){ if((((int)roundf64(x/span))%5)){ x+=span; continue; }
+        real lx=tnsInterpolate(L,R,tnsGetRatiod(xmin,xmax,x));
+        tnsVertex2d(lx,U);tnsVertex2d(lx,B); x+=span;
+    } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor*AlphaFactor); tnsPackAs(GL_LINES);
+    x=startx; while(x<xmax){ if((((int)roundf64(x/span))%10)){ x+=span; continue; }
+        real lx=tnsInterpolate(L,R,tnsGetRatiod(xmin,xmax,x));
+        tnsVertex2d(lx,U);tnsVertex2d(lx,B); x+=span;
+    } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor); tnsPackAs(GL_LINES);
+
+    for(int i=0;i<20;i++){ span=1e-5*pow(10,i); if(span>MinSpanH) break; }
+    real starty=((real)((int)(ymin/span)))*span; real y=starty;
+    while(y<ymax){
+        real ly=tnsInterpolate(B,U,tnsGetRatiod(ymin,ymax,y));
+        tnsVertex2d(L,ly);tnsVertex2d(R,ly); y+=span;
+    } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor*AlphaFactor*AlphaFactor); tnsPackAs(GL_LINES);
+    y=starty; while(y<ymax){ if((((int)roundf64(y/span))%5)){ y+=span; continue; }
+        real ly=tnsInterpolate(B,U,tnsGetRatiod(ymin,ymax,y));
+        tnsVertex2d(L,ly);tnsVertex2d(R,ly); y+=span;
+    } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor*AlphaFactor); tnsPackAs(GL_LINES);
+    y=starty; while(y<ymax){ if((((int)roundf64(y/span))%10)){ y+=span; continue; }
+        real ly=tnsInterpolate(B,U,tnsGetRatiod(ymin,ymax,y));
+        tnsVertex2d(L,ly);tnsVertex2d(R,ly); y+=span;
+    } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor); tnsPackAs(GL_LINES);
+}

+ 1 - 4
source/lagui/la_tns_mesh.c

@@ -250,10 +250,7 @@ void tnsDrawMeshObject(tnsMeshObject* mo, int DrawAsObjectSelection, int MeshSel
         }
     }else{
         if(T->BindedShader==T->SelectionShader){
-            int i=mo->Base.SelectID; real color[4]={0,0,0,1};
-            color[0]=(real)((i & 0x000000FF)>>0)/255.0;
-            color[1]=(real)((i & 0x0000FF00)>>8)/255.0;
-            color[2]=(real)((i & 0x00FF0000)>>16)/255.0;
+            int i=mo->Base.SelectID; real color[4]={0,0,0,1}; TNS_ID_TO_COLOR(color,i);
             tnsDrawBatch(mo->Batch,"body",color,0);
         }else{
             tnsUseNormal(1);

+ 53 - 7
source/lagui/resources/la_modelling.c

@@ -3,6 +3,50 @@
 extern LA MAIN;
 extern struct _tnsMain *T;
 
+void la_ReadGLocation(tnsOffscreen* off, int x, int y,float* xyz0){
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, off->FboHandle);
+    glReadBuffer(GL_COLOR_ATTACHMENT2); glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    glReadPixels(x,y,1,1, GL_RGBA, GL_FLOAT, xyz0);
+}
+int OPINV_SetCursor(laOperator *a, laEvent *e){
+    if(!a->This || !a->This->EndInstance){ return 0; }
+    laCanvasExtra* ex=a->This->EndInstance; tnsCamera*c=ex->ViewingCamera; laUiItem* ui=ex->ParentUi;
+    tnsObject*root=ui?ui->PP.EndInstance:0; if(!root || root->Type!=TNS_OBJECT_ROOT) return 0;
+
+    float pos[4]; la_ReadGLocation(ex->DeferredOffScr, e->x-ui->L,ui->B-e->y,pos);
+    if(pos[0]>-1e20){
+        tnsVectorSet3v(root->GLocation,pos); laNotifyUsers("tns.world"); return LA_FINISHED_PASS;
+    }else
+    {
+        if(!ex->ViewingCamera){ return LA_FINISHED_PASS; }
+        real vv[4], gp[4]; tnsMatrix44d proj; tnsMatrix44d inv;
+        real focus=ex->ViewingCamera->FocusDistance, near=ex->ViewingCamera->ZMin, far=ex->ViewingCamera->ZMax;
+        tnsGetCameraViewProjection(proj,ui->R-ui->L,ui->B-ui->U,ex->ViewingCamera); tnsInverse44d(inv,proj);
+        vv[0]=(real)(e->x-ui->L)/(real)(ui->R-ui->L)*2-1; vv[0]*=focus;
+        vv[1]=(real)(ui->B-e->y)/(real)(ui->B-ui->U)*2-1; vv[1]*=focus;
+        vv[2]=tnsGetRatiod(1/near,1/far,1/focus)*focus;
+        vv[3]=focus;
+        tnsApplyTransform44dTrue(gp, inv, vv);
+        tnsVectorMultiSelf3d(gp,1/gp[3]);
+
+        real vv0[3]={0,0,-1}, vv1[3], ray[3], p0[3]; real t; tnsMatrix44d inv2;
+        tnsSelfTransformValueChanged(ex->ViewingCamera);tnsInverse44d(inv2,ex->ViewingCamera->Base.GlobalTransform);
+        tnsApplyRotation43d(vv1,inv2,vv0); 
+        tnsVectorMulti3d(vv0,vv1,focus);
+        tnsVectorAccum3d(vv0,ex->ViewingCamera->Base.GLocation);
+        tnsVectorMinus3d(ray, gp, ex->ViewingCamera->Base.GLocation);
+        tnsNormalizeSelf3d(ray);
+        if(tnsIntersectPlaneRay(vv1,vv0,ex->ViewingCamera->Base.GLocation,ray,&t)){
+            tnsVectorMultiSelf3d(ray,t); tnsVectorPlus3d(gp,ray,ex->ViewingCamera->Base.GLocation);
+        }
+
+        tnsVectorSet3v(root->GLocation,gp); laNotifyUsers("tns.world"); return LA_FINISHED_PASS;
+    }
+
+    return LA_FINISHED_PASS;
+}
+
+
 int OPCHK_ThereIsActiveObject(laPropPack *This, laStringSplitor *ss){
     if(!This || !This->EndInstance){ return 0; }
     laCanvasExtra* ex=This->EndInstance; tnsCamera*c=ex->ViewingCamera; laUiItem* ui=ex->ParentUi;
@@ -105,8 +149,7 @@ void la_PadSelectionBuffer(uint8_t* buf, int w, int h, int sx, int sy, int ex, i
     free(pad);
 }
 uint8_t* la_ReadSelection(MSelectData* sd, u8bit* buf, int x, int y, int w, int h){
-    glFlush(); glFinish(); 
-    glGetError();
+    glFlush(); glFinish(); glGetError();
     glBindFramebuffer(GL_READ_FRAMEBUFFER, sd->FBO->FboHandle);
     glReadBuffer(GL_COLOR_ATTACHMENT0);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -209,14 +252,15 @@ int OPINV_Select(laOperator *a, laEvent *e){
     tnsObject*root=ui?ui->PP.EndInstance:0; if(!root) return 0;
     tnsMeshObject* mo=root->Active;
 
+    int is_geo=0;
     if(strSame(strGetArgumentString(a->ExtraInstructionsP, "mode"), "toggle")){
         if(mo && mo->Base.Type==TNS_OBJECT_MESH && mo->Mode==TNS_MESH_EDIT_MODE){
             if(tnsMMeshAnySelected(mo)) tnsMMeshDeselectAll(mo); else tnsMMeshSelectAll(mo);
-            tnsInvalidateMeshBatch(mo);
+            tnsInvalidateMeshBatch(mo); is_geo=1;
         }else{
             if(tnsAnyObjectsSelected(root)) tnsDeselectAllObjects(root); else tnsSelectAllObjects(root);
         }
-        laNotifyUsers("tns.world"); laRecordAndPush(0,"tns.world", "Toggle selection",mo->Mode==TNS_MESH_EDIT_MODE?TNS_HINT_GEOMETRY:TNS_HINT_TRANSFORM);
+        laNotifyUsers("tns.world"); laRecordAndPush(0,"tns.world", "Toggle selection",is_geo?TNS_HINT_GEOMETRY:TNS_HINT_TRANSFORM);
         return LA_FINISHED;
     }
     
@@ -271,6 +315,7 @@ int OPMOD_Select(laOperator *a, laEvent *e){
     int Append=e->SpecialKeyBit&LA_KEY_SHIFT; if(Append) DeselectAll=0;
     int Remove=e->SpecialKeyBit&LA_KEY_ALT; if(Remove) DeselectAll=0;
 
+    int is_geo=0;
     if(se->InSelect && e->Type==LA_L_MOUSE_UP){
         if(mo && mo->Base.Type==TNS_OBJECT_MESH && mo->Mode==TNS_MESH_EDIT_MODE){
             la_DoMeshSelect(mo, 0, ex->SelectMode, DeselectAll, 0, 0);
@@ -280,7 +325,7 @@ int OPMOD_Select(laOperator *a, laEvent *e){
                 la_DoMeshSelect(mo, p, ex->SelectMode, 0, !Remove, 0);
             }
             tnsMMeshEnsureSelection(mo,ex->SelectMode);
-            tnsInvalidateMeshBatch(mo);
+            tnsInvalidateMeshBatch(mo); is_geo=1;
         }else{
             la_DoObjectSelect(se->root, 0, ex, DeselectAll, 0, 0);
             int len; int* ids=la_SelectGetBox(se->sd, ex->ClickedX, ex->ClickedY, e->x-ui->L, e->y-ui->U, &len);
@@ -288,7 +333,7 @@ int OPMOD_Select(laOperator *a, laEvent *e){
                 int id=ids[i]; if(id && id<se->sd->next){ la_DoObjectSelect(se->root, se->sd->Refs[id], ex, 0, !Remove, 0);  }
             }
         }
-        laNotifyUsers("tns.world"); laRecordAndPush(0,"tns.world","Box selection",mo->Mode==TNS_MESH_EDIT_MODE?TNS_HINT_GEOMETRY:TNS_HINT_TRANSFORM);
+        laNotifyUsers("tns.world"); laRecordAndPush(0,"tns.world","Box selection",is_geo?TNS_HINT_GEOMETRY:TNS_HINT_TRANSFORM);
         ex->DrawCursor=0;
         la_FreeSelectData(se->sd);
         laRedrawCurrentPanel();
@@ -1046,7 +1091,7 @@ int OPINV_Make(laOperator *a, laEvent *e){
     tnsObject*root=ui?ui->PP.EndInstance:0; if(!root) return 0;
     tnsMeshObject* mo=root->Active;
     
-    if(mo->Base.Type!=TNS_OBJECT_MESH || mo->Mode!=TNS_MESH_EDIT_MODE){ return LA_CANCELED; }
+    if(!mo||mo->Base.Type!=TNS_OBJECT_MESH || mo->Mode!=TNS_MESH_EDIT_MODE){ return LA_CANCELED; }
 
     MMakeData md={0};
     la_GetSelectionIslands(mo,&md,ex->SelectMode);
@@ -1214,6 +1259,7 @@ void la_RegisterModellingOperators(){
     laOperatorType *at;
     laEnumProp *ep;
 
+    laCreateOperatorType("M_set_cursor", "Set Cursor", "Set cursor in the viewport", OPCHK_ViewportAndSceneExists, 0, 0, OPINV_SetCursor, 0, 0, LA_EXTRA_TO_PANEL);
     laCreateOperatorType("M_toggle_edit_mode", "Toggle Edit Mode", "Toggle edit mode of the active object", OPCHK_ThereIsActiveObject, 0, 0, OPINV_ToggleEdit, 0, 0, 0);
     laCreateOperatorType("M_select", "Select", "Select things in the viewport", OPCHK_ViewportAndSceneExists, 0, 0, OPINV_Select, OPMOD_Select, 0, LA_EXTRA_TO_PANEL);
     laCreateOperatorType("M_grab", "Grab", "Grab things and move around", OPCHK_ViewportAndSceneExists, 0, 0, OPINV_Grab, OPMOD_Transformation, 0, LA_EXTRA_TO_PANEL);

+ 3 - 3
source/lagui/resources/la_properties.c

@@ -484,10 +484,10 @@ void* laget_CurrentRackPage(laRackPageCollection* c){
     return c->CurrentPage;
 }
 
-void *tnsget_TnsMain(void *unused){
+void *tnsget_TnsMain(void *unused,void *unused2){
     return T;
 }
-void *tnsget_World(void *unused){
+void *tnsget_World(void *unused,void *unused2){
     return &T->World;
 }
 void *tnsread_World(void *unused, void *inst){
@@ -1377,7 +1377,7 @@ void la_RegisterInternalProps(){
             laAddEnumItem(ep, "PERSP", "Perspective", "Camera in linear perspective", 0);
             laAddEnumItem(ep, "ORTHO", "Orthographic", "Camera in orthographic view", 0);
         }
-        laAddFloatProperty(p, "fov", "FOV", "Field Of View", 0, 0, "^", rad(160), rad(1), rad(0.1), rad(60), 0, offsetof(tnsCamera, FOV), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LA_UDF_IS_RAD);
+        laAddFloatProperty(p, "fov", "FOV", "Field Of View", 0, 0, "^", rad(160), rad(1), rad(0.1), rad(60), 0, offsetof(tnsCamera, FOV), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LA_RAD_ANGLE);
         laAddFloatProperty(p, "depth_range", "Depth Range", "Depth Range To Map From 0 To 1", 0, "Near,Far", 0, 0, 0, 0.1, 0, 0, offsetof(tnsCamera, ZMin), 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0);
         laAddFloatProperty(p, "focus_distance", "Focus Distance", "For Viewing Camera To Determin Zooming Center", 0, 0, 0, 0, 0, 0.1, 100, 0, offsetof(tnsCamera, FocusDistance), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
         laAddFloatProperty(p, "orth_scale", "Scale", "Orthographical Camera Scale", 0, 0, "^^", 1000, 0.001, 0.1, 1, 0, offsetof(tnsCamera, OrthScale), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

+ 20 - 14
source/lagui/resources/la_widgets.c

@@ -577,6 +577,7 @@ void la_FloatDraw(laUiItem *ui, int h){
     int s, State;
     int IsVertical=ui->Flags&LA_UI_FLAGS_TRANSPOSE;
     int NoDecal=ui->Flags&LA_UI_FLAGS_NO_DECAL;
+    int IsRad=ui->PP.LastPs->p->IsRadAngle;
 
     if (laIsPropertyReadOnly(&ui->PP) && !NoDecal) ui->State = LA_BT_DISABLED;
 
@@ -596,11 +597,10 @@ void la_FloatDraw(laUiItem *ui, int h){
             _L = ui->L + i * Seg; _R=_L+Seg;
         }
 
-        buf[0] = L'\0';
-        strPrintFloatAfter(buf, 48, 3, Data[i]);
+        buf[0] = L'\0'; if(i<8)strcat(buf, &prefix[i]);
+        strPrintFloatAfter(buf, 48, 3, IsRad?deg(Data[i]):Data[i]);
         strAppend(buf, ui->PP.LastPs->p->Unit ? transLate(ui->PP.LastPs->p->Unit) : "");
         buf2[0] = L'\0'; if(Len==1){ strcat(buf2, transLate(ui->PP.LastPs->p->Name)); }
-        if(i<8)strcat(buf2, &prefix[i]);
 
         if (ui->Extra && ui->Extra->On == i + 1){
             Original = ui->State;
@@ -1709,18 +1709,20 @@ int OPMOD_IntArrayHorizon(laOperator *a, laEvent *e){
         ui->Extra->On = (IsVertical ? la_DetectRow(ui, e->y) : la_DetectColumn(ui, e->x, Len)) + 1;
         if (ui->Extra->On > Len) return LA_RUNNING;
         laGetIntArray(&ui->PP, &TmpArr);
-        uit->TargetIndexVali = TmpArr[ui->Extra->On - 1];
+        uit->TargetIndexValf = TmpArr[ui->Extra->On - 1];
         laRedrawCurrentPanel();
         return LA_RUNNING;
     }
     if (e->Type == LA_MOUSEMOVE && ui->Extra->On){
         if(ui->Extra->Edit){ return LA_RUNNING; }
         int dist=abs(e->x - uit->LastX);
-        if (dist > MAIN.ValuatorThreshold){
-            laGetIntArray(&ui->PP, &TmpArr);
-            uit->TargetIndexVali = TmpArr[ui->Extra->On - 1];
-            uit->TargetIndexVali += ((e->x - uit->LastX) > 0 ? 1 : -1) * ip->Step;
-            laSetIntArraySingle(&ui->PP, ui->Extra->On - 1, uit->TargetIndexVali);
+        if (dist > MAIN.ValuatorThreshold || uit->Dragging){
+            int min,max,Ranged = laGetIntRange(&ui->PP, &min, &max); real step=ip->Step; if(Ranged){ step=(real)(max-min)/(ui->R-ui->L); }
+            //laGetIntArray(&ui->PP, &TmpArr);
+            //uit->TargetIndexVali = TmpArr[ui->Extra->On - 1];
+            int delta=e->x-uit->LastX; if(!uit->Dragging) delta=delta>0?1:-1;
+            uit->TargetIndexValf +=  delta*step;
+            laSetIntArraySingle(&ui->PP, ui->Extra->On - 1, uit->TargetIndexValf);
             uit->LastX = e->x;
             uit->LastY = e->y;
             uit->Dragging = 1;
@@ -1794,6 +1796,7 @@ int OPMOD_FloatArrayHorizon(laOperator *a, laEvent *e){
     int Len = laGetArrayLength(&ui->PP);
     int IsVertical=(ui->Flags&LA_UI_FLAGS_TRANSPOSE)!=0;
     int NoEvent = ui->Flags&LA_UI_FLAGS_NO_EVENT;
+    int IsRad=ui->PP.LastPs->p->IsRadAngle;
 
     if (!laIsInUiItem(ui, e->x, e->y) && !ui->Extra->On){
         ui->State = LA_UI_NORMAL;
@@ -1836,10 +1839,12 @@ int OPMOD_FloatArrayHorizon(laOperator *a, laEvent *e){
     if (e->Type == LA_MOUSEMOVE && ui->Extra->On){
         if(uit->Edit){ return LA_RUNNING; }
         int dist=abs(e->x - uit->LastX);
-        if (dist > MAIN.ValuatorThreshold){
-            laGetIntArray(&ui->PP, &TmpArr);
-            uit->TargetIndexVali = TmpArr[ui->Extra->On - 1];
-            uit->TargetIndexValf += ((e->x - uit->LastX) > 0 ? 1 : -1) * fp->Step;
+        if (dist > MAIN.ValuatorThreshold || uit->Dragging){
+            real min,max; int Ranged = laGetFloatRange(&ui->PP, &min, &max); real step=fp->Step; if(Ranged){ step=(max-min)/(ui->R-ui->L); }
+            laGetFloatArray(&ui->PP, &TmpArr);
+            uit->TargetIndexValf = TmpArr[ui->Extra->On - 1];
+            int delta=e->x-uit->LastX; if(!uit->Dragging) delta=delta>0?1:-1;
+            uit->TargetIndexValf +=  delta*step;
             laSetFloatArraySingle(&ui->PP, ui->Extra->On - 1, uit->TargetIndexValf);
             uit->LastX = e->x;
             uit->LastY = e->y;
@@ -1863,7 +1868,7 @@ int OPMOD_FloatArrayHorizon(laOperator *a, laEvent *e){
                 uit->On=SelectOn;
                 laGetFloatArray(&ui->PP, &TmpArr);
                 uit->TargetIndexValf = TmpArr[ui->Extra->On - 1];
-                strPrintFloatAfter(buf, 32, 5, uit->TargetIndexValf);
+                strPrintFloatAfter(buf, 32, 5, IsRad?deg(uit->TargetIndexValf):uit->TargetIndexValf);
                 strBeginEdit(&uit->Edit,buf);
                 strSelectLineAll(uit->Edit);
             }
@@ -1877,6 +1882,7 @@ int OPMOD_FloatArrayHorizon(laOperator *a, laEvent *e){
         if (e->key == LA_KEY_ENTER && uit->Edit){
             char* buf=strEndEdit(&uit->Edit, 0);
             real Result; sscanf(buf, "%lf", &Result); free(buf);
+            if(IsRad) Result=rad(Result);
             laSetFloatArraySingle(&ui->PP, ui->Extra->On - 1, Result);
             laRecordAndPushProp(&ui->PP,0); laMarkPropChanged(&ui->PP);
             uit->Dragging = 0;

+ 29 - 20
source/lagui/resources/la_widgets_viewers.c

@@ -122,7 +122,8 @@ void la_RootObjectDraw(laBoxedTheme *bt, tnsObject *root, laUiItem* ui){
 
     tnsDrawToOffscreen(e->DeferredOffScr,3,TNS_ATTACHMENT_ARRAY_0_1_2);
     tnsViewportWithScissor(0, 0, W, H);
-    tnsClearColorv(laThemeColor(bt,LA_BT_NORMAL)); tnsClearAll();
+    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();
@@ -133,13 +134,27 @@ void la_RootObjectDraw(laBoxedTheme *bt, tnsObject *root, laUiItem* ui){
     tnsUnbindTexture(); tnsUniformUseTexture(T->immShader,0,0); tnsUseMultiplyColor(0);
     glPointSize(6); glLineWidth(3);
     tnsDrawObjectTree(root, 0, 0, e->SelectMode);
-    glPointSize(1); glLineWidth(2);
+    glPointSize(1); glLineWidth(3);
 
-    glDepthMask(GL_FALSE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //glEnable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(1,1);
+    glDepthMask(GL_FALSE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glEnable(GL_POLYGON_OFFSET_LINE); glEnable(GL_POLYGON_OFFSET_POINT); glPolygonOffset(1,1);
     tnsDrawObjectTree(root, root->Active, 1, 0);
     glDepthMask(GL_TRUE); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     glLineWidth(1);
 
+    if (!e->LineDrawingMode && e->ShowFloorGrid){
+        tnsUseNoTexture();
+        real* color=laThemeColor(bt,LA_BT_BORDER); tnsColor4d(LA_COLOR3(color),0.4);
+        tnsDrawFloor(e->GridSize, e->GridSpan, e->ShowAxis);
+        tnsFlush();
+    }
+
+    glDisable(GL_DEPTH_TEST);
+    tnsDrawCursor(root);
+    glPointSize(8);
+    tnsDrawObjectOrigins(root,root->Active,0); tnsFlush();
+    glPointSize(1);
+    glEnable(GL_DEPTH_TEST);
+
     //laInvoke(0,"M_select",e,&ui->ExtraPP,0,0);
 
     //glColorMask(GL_FALSE, GL_FALSE,GL_FALSE,GL_FALSE);
@@ -148,13 +163,6 @@ void la_RootObjectDraw(laBoxedTheme *bt, tnsObject *root, laUiItem* ui){
     tnsFlush();
     //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 
-    if (!e->LineDrawingMode && e->ShowFloorGrid){
-        tnsUseNoTexture();
-        real* color=laThemeColor(bt,LA_BT_BORDER); tnsColor4d(LA_COLOR3(color),0.4);
-        tnsDrawFloor(e->GridSize, e->GridSpan, e->ShowAxis);
-        tnsFlush();
-    }
-
     glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND);
 
     tnsDrawToOffscreen(e->OffScr, 1,0);
@@ -190,8 +198,10 @@ void la_RootObjectDrawOverlay(laUiItem *ui, int h){
                 tnsPackAs(GL_LINE_LOOP);
             }
             tnsColor4dv(laThemeColor(bt,LA_BT_TEXT));
-            tnsVertex2d(e->OnX, ui->U); tnsVertex2d(e->OnX, ui->B);
-            tnsVertex2d(ui->L, e->OnY); tnsVertex2d(ui->R, e->OnY);
+            int drawx=(e->DrawCursor==LA_CANVAS_CURSOR_CROSS)||(e->DrawCursor==LA_CANVAS_CURSOR_X);
+            int drawy=(e->DrawCursor==LA_CANVAS_CURSOR_CROSS)||(e->DrawCursor==LA_CANVAS_CURSOR_Y);
+            if(drawx) tnsVertex2d(e->OnX, ui->U); tnsVertex2d(e->OnX, ui->B);
+            if(drawy) tnsVertex2d(ui->L, e->OnY); tnsVertex2d(ui->R, e->OnY);
             tnsPackAs(GL_LINES);
         }
     }
@@ -383,19 +393,17 @@ void la_CanvasDrawOverlay(laUiItem *ui, int h){
 
     if(MAIN.CurrentWindow->MaximizedUi!=ui){
         tnsColor4dv(laThemeColor(bt,LA_BT_BORDER));
-        tnsVertex2d(ui->L, ui->U);
-        tnsVertex2d(ui->R, ui->U);
-        tnsVertex2d(ui->R, ui->B);
-        tnsVertex2d(ui->L, ui->B);
+        tnsVertex2d(ui->L, ui->U); tnsVertex2d(ui->R, ui->U);
+        tnsVertex2d(ui->R, ui->B); tnsVertex2d(ui->L, ui->B);
         tnsPackAs(GL_LINE_LOOP);
     }
 
     if (e->DrawCursor){
         tnsColor4dv(laThemeColor(bt,LA_BT_TEXT));
-        tnsVertex2d(e->OnX, ui->U);
-        tnsVertex2d(e->OnX, ui->B);
-        tnsVertex2d(ui->L, e->OnY);
-        tnsVertex2d(ui->R, e->OnY);
+        int drawx=(e->DrawCursor==LA_CANVAS_CURSOR_CROSS)||(e->DrawCursor==LA_CANVAS_CURSOR_X);
+        int drawy=(e->DrawCursor==LA_CANVAS_CURSOR_CROSS)||(e->DrawCursor==LA_CANVAS_CURSOR_Y);
+        if(drawx) tnsVertex2d(e->OnX, ui->U); tnsVertex2d(e->OnX, ui->B);
+        if(drawy) tnsVertex2d(ui->L, e->OnY); tnsVertex2d(ui->R, e->OnY);
         tnsPackAs(GL_LINES);
         tnsFlush();
     }
@@ -1019,6 +1027,7 @@ void la_RegisterUiTypesViewerWidgets(){
     laAssignNewKey(km, 0, "TNS_align_camera_to_view", LA_KM_SEL_UI_EXTRA, LA_KEY_ALT | LA_KEY_SHIFT, LA_R_MOUSE_DOWN, 0, 0);
     laAssignNewKey(km, 0, "TNS_align_view_to_camera", LA_KM_SEL_UI_EXTRA, 0, LA_KEY_DOWN, '0', 0);
 
+    laAssignNewKey(km, 0, "M_set_cursor", LA_KM_SEL_UI_EXTRA, 0, LA_L_MOUSE_DOWN, 0, 0);
     laAssignNewKey(km, 0, "M_toggle_edit_mode", LA_KM_SEL_UI_EXTRA, 0, LA_KEY_DOWN, LA_KEY_TAB, 0);
     laAssignNewKey(km, 0, "M_select", LA_KM_SEL_UI_EXTRA, LA_KEY_ALT, LA_R_MOUSE_DOWN, 0, 0);
     laAssignNewKey(km, 0, "M_select", LA_KM_SEL_UI_EXTRA, LA_KEY_SHIFT, LA_R_MOUSE_DOWN, 0, 0);