|
@@ -118,7 +118,7 @@ void la_PopulateSelectDataObjects(MSelectData* sd, tnsObject* root, tnsCamera* c
|
|
tnsApplyCameraView(w,h,camera);
|
|
tnsApplyCameraView(w,h,camera);
|
|
glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
|
glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_DEPTH_TEST);
|
|
- tnsDrawObjectTree(root,0,0,0);
|
|
|
|
|
|
+ tnsDrawObjectTree(root,0,0,0,0,0,0);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_DEPTH_TEST);
|
|
}
|
|
}
|
|
void la_PopulateSelectVerts(MSelectData* sd, tnsMeshObject* mo){
|
|
void la_PopulateSelectVerts(MSelectData* sd, tnsMeshObject* mo){
|
|
@@ -139,7 +139,7 @@ void la_PopulateSelectEdges(MSelectData* sd, tnsMeshObject* mo){
|
|
}
|
|
}
|
|
sd->nextE++;
|
|
sd->nextE++;
|
|
}
|
|
}
|
|
-void la_PopulateSelectDataPrimitives(MSelectData* sd, tnsMeshObject* mo, tnsCamera* camera, int WhatPrim){
|
|
|
|
|
|
+void la_PopulateSelectDataPrimitives(MSelectData* sd, tnsMeshObject* mo, tnsCamera* camera, int WhatPrim, int SelectThrough){
|
|
int DoVerts=(WhatPrim==LA_CANVAS_SELECT_MODE_VERTS),DoEdges=(WhatPrim==LA_CANVAS_SELECT_MODE_EDGES);
|
|
int DoVerts=(WhatPrim==LA_CANVAS_SELECT_MODE_VERTS),DoEdges=(WhatPrim==LA_CANVAS_SELECT_MODE_EDGES);
|
|
int Knife=(WhatPrim==LA_CANVAS_SELECT_MODE_KNIFE);
|
|
int Knife=(WhatPrim==LA_CANVAS_SELECT_MODE_KNIFE);
|
|
if(DoVerts || Knife){ la_PopulateSelectVerts(sd,mo); }
|
|
if(DoVerts || Knife){ la_PopulateSelectVerts(sd,mo); }
|
|
@@ -150,12 +150,17 @@ void la_PopulateSelectDataPrimitives(MSelectData* sd, tnsMeshObject* mo, tnsCame
|
|
tnsViewportWithScissor(0,0,w,h);tnsResetViewMatrix();tnsResetModelMatrix();tnsResetProjectionMatrix();
|
|
tnsViewportWithScissor(0,0,w,h);tnsResetViewMatrix();tnsResetModelMatrix();tnsResetProjectionMatrix();
|
|
tnsApplyCameraView(w,h,camera);
|
|
tnsApplyCameraView(w,h,camera);
|
|
glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
|
glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
|
- glEnable(GL_DEPTH_TEST);
|
|
|
|
- tnsPushMatrix(); tnsApplyObjectMatrix(mo);
|
|
|
|
- if(Knife){ glPointSize(5); }
|
|
|
|
|
|
+ tnsPushMatrix(); tnsApplyObjectMatrix(mo);glEnable(GL_DEPTH_TEST);
|
|
|
|
+ if(!SelectThrough){
|
|
|
|
+ glDepthMask(GL_TRUE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
|
|
+ tnsUniformUseOffset(T->SelectionShader,0);
|
|
|
|
+ tnsDrawBatch(mo->Batch,"body",0,0);
|
|
|
|
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_FALSE);
|
|
|
|
+ }
|
|
|
|
+ tnsUniformUseOffset(T->SelectionShader,1);
|
|
if(DoEdges || Knife){ tnsDrawBatch(mo->Batch, "edges_select",0,0); }
|
|
if(DoEdges || Knife){ tnsDrawBatch(mo->Batch, "edges_select",0,0); }
|
|
if(DoVerts || Knife){ tnsDrawBatch(mo->Batch, "verts_select",0,0); }
|
|
if(DoVerts || Knife){ tnsDrawBatch(mo->Batch, "verts_select",0,0); }
|
|
- if(Knife){ glPointSize(1); }
|
|
|
|
|
|
+ tnsUniformUseOffset(T->SelectionShader,0);
|
|
tnsPopMatrix();
|
|
tnsPopMatrix();
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_DEPTH_TEST);
|
|
}
|
|
}
|
|
@@ -204,18 +209,23 @@ uint8_t* la_ReadSelectionBox(MSelectData* sd, int uix, int uiy, int uix2, int ui
|
|
}
|
|
}
|
|
int la_SelectGetClosest(MSelectData* sd, int uix, int uiy, int radius, int *ElemType){
|
|
int la_SelectGetClosest(MSelectData* sd, int uix, int uiy, int radius, int *ElemType){
|
|
*ElemType=0; uint8_t* buf=la_ReadSelectionRadius(sd, uix, uiy, radius); if(!buf) return 0;
|
|
*ElemType=0; uint8_t* buf=la_ReadSelectionRadius(sd, uix, uiy, radius); if(!buf) return 0;
|
|
- int w=radius*2; int MinD=INT_MAX; int MinID=0, d, elemtype=0;
|
|
|
|
|
|
+ int w=radius*2; int MinD=INT_MAX,MinDe=INT_MAX; int MinID=0,MinIDe=0, d, elemtype=0;
|
|
for(int i=0;i<w;i++){
|
|
for(int i=0;i<w;i++){
|
|
for(int j=0;j<w;j++){
|
|
for(int j=0;j<w;j++){
|
|
- uint8_t* p=&buf[(i*w+j)*4]; int id=(p[0])|(p[1]<<8)|((p[2]<<16)&(~TNS_MMESH_TYPE_BIT));
|
|
|
|
- if(id && (d=tnsDistIdv2(i,j, radius, radius))<MinD ){ MinD=d; MinID=id; elemtype=((p[2]<<16)&TNS_MMESH_TYPE_BIT); }
|
|
|
|
|
|
+ uint8_t* p=&buf[(i*w+j)*4]; int id=(p[0])|(p[1]<<8)|((p[2]<<16)&(~TNS_MMESH_TYPE_BIT)); if(!id){continue;}
|
|
|
|
+ d=tnsDistIdv2(i,j, radius, radius); elemtype=((p[2]<<16)&TNS_MMESH_TYPE_BIT);
|
|
|
|
+ if(elemtype==TNS_MMESH_EDGE_BIT){ if(d<MinDe){ MinDe=d; MinIDe=id; } }
|
|
|
|
+ elif(d<MinD){ MinD=d; MinID=id; }
|
|
//printf("%d ",buf[(i*w+j)*4]);
|
|
//printf("%d ",buf[(i*w+j)*4]);
|
|
}
|
|
}
|
|
//printf("\n");
|
|
//printf("\n");
|
|
}
|
|
}
|
|
|
|
+ printf("%d %d\n",MinID, MinIDe);
|
|
free(buf);
|
|
free(buf);
|
|
- *ElemType=elemtype;
|
|
|
|
- return MinID;
|
|
|
|
|
|
+ if(MinID && MinIDe){ if(MinD<MinDe*5){ *ElemType=0; return MinID; } }
|
|
|
|
+ if(MinIDe){ *ElemType=TNS_MMESH_EDGE_BIT; return MinIDe; }
|
|
|
|
+ if(MinID){ *ElemType=0; return MinID; }
|
|
|
|
+ *ElemType=0; return 0;
|
|
}
|
|
}
|
|
int* la_SelectGetBox(MSelectData* sd, int uix, int uiy, int uix2, int uiy2, int* r_length){
|
|
int* la_SelectGetBox(MSelectData* sd, int uix, int uiy, int uix2, int uiy2, int* r_length){
|
|
uint8_t* buf=la_ReadSelectionBox(sd, uix, uiy, uix2, uiy2); if(!buf) return 0;
|
|
uint8_t* buf=la_ReadSelectionBox(sd, uix, uiy, uix2, uiy2); if(!buf) return 0;
|
|
@@ -308,7 +318,7 @@ int OPINV_Select(laOperator *a, laEvent *e){
|
|
int Append=e->SpecialKeyBit&LA_KEY_SHIFT; if(Append) DeselectAll=0;
|
|
int Append=e->SpecialKeyBit&LA_KEY_SHIFT; if(Append) DeselectAll=0;
|
|
|
|
|
|
if(mo && mo->Base.Type==TNS_OBJECT_MESH && mo->Mode==TNS_MESH_EDIT_MODE){
|
|
if(mo && mo->Base.Type==TNS_OBJECT_MESH && mo->Mode==TNS_MESH_EDIT_MODE){
|
|
- la_PopulateSelectDataPrimitives(sd, mo, ex->ViewingCamera, SelectMode);
|
|
|
|
|
|
+ la_PopulateSelectDataPrimitives(sd, mo, ex->ViewingCamera, SelectMode, ex->SelectThrough);
|
|
if(strSame(strGetArgumentString(a->ExtraInstructionsP, "mode"), "box")){
|
|
if(strSame(strGetArgumentString(a->ExtraInstructionsP, "mode"), "box")){
|
|
MSelectExtra* se=memAcquire(sizeof(MSelectExtra));
|
|
MSelectExtra* se=memAcquire(sizeof(MSelectExtra));
|
|
ex->OnX=e->x; ex->OnX=e->y;
|
|
ex->OnX=e->x; ex->OnX=e->y;
|
|
@@ -1306,21 +1316,21 @@ STRUCTURE(MKnifeElement){
|
|
void* p;
|
|
void* p;
|
|
int Type;
|
|
int Type;
|
|
};
|
|
};
|
|
-void la_KnifeUpdateToolBatch(MSelectExtra* se,tnsObject* o){
|
|
|
|
- if(se->root->ExtraBatch) tnsDeleteBatch(se->root->ExtraBatch); se->root->ExtraBatch=0;
|
|
|
|
|
|
+void la_KnifeUpdateToolBatch(MSelectExtra* se,tnsMeshObject* o){
|
|
|
|
+ if(o->ExtraBatch) tnsDeleteBatch(o->ExtraBatch); o->ExtraBatch=0;
|
|
int count=lstCountElements(&se->KnifeElements); if((!count) && (!se->PendingElem)) return;
|
|
int count=lstCountElements(&se->KnifeElements); if((!count) && (!se->PendingElem)) return;
|
|
float* points=calloc((count+1)*3,sizeof(real));
|
|
float* points=calloc((count+1)*3,sizeof(real));
|
|
float* p=points; real tmp[3],trans[4];
|
|
float* p=points; real tmp[3],trans[4];
|
|
for(MKnifeElement* ke=se->KnifeElements.pFirst;ke;ke=ke->Item.pNext){
|
|
for(MKnifeElement* ke=se->KnifeElements.pFirst;ke;ke=ke->Item.pNext){
|
|
if(ke->Type==TNS_MMESH_EDGE_BIT){ tnsMEdge* me=ke->p; tnsVectorSet3v(tmp,me->vl->p); tnsVectorAccum3d(tmp,me->vr->p);
|
|
if(ke->Type==TNS_MMESH_EDGE_BIT){ tnsMEdge* me=ke->p; tnsVectorSet3v(tmp,me->vl->p); tnsVectorAccum3d(tmp,me->vr->p);
|
|
- tnsVectorMultiSelf3d(tmp,0.5); tnsApplyTransform43d(trans,o->GlobalTransform,tmp); tnsVectorSet3v(p,trans); }
|
|
|
|
- else{ tnsMVert* mv=ke->p; tnsApplyTransform43d(trans,o->GlobalTransform,mv->p); tnsVectorSet3v(p,trans); }
|
|
|
|
|
|
+ tnsVectorMultiSelf3d(tmp,0.5); tnsApplyTransform43d(trans,o->Base.GlobalTransform,tmp); tnsVectorSet3v(p,trans); }
|
|
|
|
+ else{ tnsMVert* mv=ke->p; tnsApplyTransform43d(trans,o->Base.GlobalTransform,mv->p); tnsVectorSet3v(p,trans); }
|
|
p+=3;
|
|
p+=3;
|
|
}
|
|
}
|
|
if(se->PendingElem){
|
|
if(se->PendingElem){
|
|
if(se->PendingElemType==TNS_MMESH_EDGE_BIT){ tnsMEdge* me=se->PendingElem; tnsVectorSet3v(tmp,me->vl->p); tnsVectorAccum3d(tmp,me->vr->p);
|
|
if(se->PendingElemType==TNS_MMESH_EDGE_BIT){ tnsMEdge* me=se->PendingElem; tnsVectorSet3v(tmp,me->vl->p); tnsVectorAccum3d(tmp,me->vr->p);
|
|
- tnsVectorMultiSelf3d(tmp,0.5); tnsApplyTransform43d(trans,o->GlobalTransform,tmp); tnsVectorSet3v(p,trans); }
|
|
|
|
- else{ tnsMVert* mv=se->PendingElem; tnsApplyTransform43d(trans,o->GlobalTransform,mv->p); tnsVectorSet3v(p,trans); }
|
|
|
|
|
|
+ tnsVectorMultiSelf3d(tmp,0.5); tnsApplyTransform43d(trans,o->Base.GlobalTransform,tmp); tnsVectorSet3v(p,trans); }
|
|
|
|
+ else{ tnsMVert* mv=se->PendingElem; tnsApplyTransform43d(trans,o->Base.GlobalTransform,mv->p); tnsVectorSet3v(p,trans); }
|
|
}elif(count){
|
|
}elif(count){
|
|
tnsVectorSet3v(p,p-3);
|
|
tnsVectorSet3v(p,p-3);
|
|
}
|
|
}
|
|
@@ -1328,6 +1338,7 @@ void la_KnifeUpdateToolBatch(MSelectExtra* se,tnsObject* o){
|
|
tnsBatch* batch=tnsCreateBatch(count+1,3,points,0,0,0,0); tnsBatchCommand*c;
|
|
tnsBatch* batch=tnsCreateBatch(count+1,3,points,0,0,0,0); tnsBatchCommand*c;
|
|
c=tnsCreateCommand(batch, "hovering_point", 1, 3, GL_POINTS, &elem, 0);
|
|
c=tnsCreateCommand(batch, "hovering_point", 1, 3, GL_POINTS, &elem, 0);
|
|
tnsCommandUseUniformColor(c,laAccentColor(LA_BT_SVERTEX));
|
|
tnsCommandUseUniformColor(c,laAccentColor(LA_BT_SVERTEX));
|
|
|
|
+ tnsCommandUseWidth(c, 8);
|
|
if(count){
|
|
if(count){
|
|
c=tnsCreateCommand(batch, "edges", count+(se->IsLoop?0:1), 3, se->IsLoop?GL_LINE_LOOP:GL_LINE_STRIP, 0, 0);
|
|
c=tnsCreateCommand(batch, "edges", count+(se->IsLoop?0:1), 3, se->IsLoop?GL_LINE_LOOP:GL_LINE_STRIP, 0, 0);
|
|
tnsCommandUseUniformColor(c,laAccentColor(LA_BT_NORMAL));
|
|
tnsCommandUseUniformColor(c,laAccentColor(LA_BT_NORMAL));
|
|
@@ -1336,7 +1347,7 @@ void la_KnifeUpdateToolBatch(MSelectExtra* se,tnsObject* o){
|
|
tnsCommandUseUniformColor(c,laAccentColor(LA_BT_NORMAL));
|
|
tnsCommandUseUniformColor(c,laAccentColor(LA_BT_NORMAL));
|
|
tnsCommandUseWidth(c, 6);
|
|
tnsCommandUseWidth(c, 6);
|
|
}
|
|
}
|
|
- se->root->ExtraBatch=batch;
|
|
|
|
|
|
+ o->ExtraBatch=batch;
|
|
free(points);
|
|
free(points);
|
|
}
|
|
}
|
|
int la_KnifeIsDuplicated(MSelectExtra* se, void* ref){
|
|
int la_KnifeIsDuplicated(MSelectExtra* se, void* ref){
|
|
@@ -1366,7 +1377,7 @@ int la_KnifeRegisterCuts(MSelectExtra* se, tnsMeshObject* mo, int TryClose){
|
|
if(changed){ tnsMMeshRefreshIndex(mo); tnsMMeshCalculateNormal(mo); }
|
|
if(changed){ tnsMMeshRefreshIndex(mo); tnsMMeshCalculateNormal(mo); }
|
|
return changed;
|
|
return changed;
|
|
}
|
|
}
|
|
-void la_KnifeFinish(MSelectExtra* se, tnsObject*o){
|
|
|
|
|
|
+void la_KnifeFinish(MSelectExtra* se, tnsMeshObject*o){
|
|
if(o->ExtraBatch) tnsDeleteBatch(o->ExtraBatch); o->ExtraBatch=0;
|
|
if(o->ExtraBatch) tnsDeleteBatch(o->ExtraBatch); o->ExtraBatch=0;
|
|
while(lstPopPointer(&se->KnifeElements));
|
|
while(lstPopPointer(&se->KnifeElements));
|
|
la_FreeSelectData(se->sd); memFree(se);
|
|
la_FreeSelectData(se->sd); memFree(se);
|
|
@@ -1411,7 +1422,7 @@ int OPINV_Knife(laOperator *a, laEvent *e){
|
|
int SelectMode=LA_CANVAS_SELECT_MODE_KNIFE;
|
|
int SelectMode=LA_CANVAS_SELECT_MODE_KNIFE;
|
|
if(strSame(strGetArgumentString(a->ExtraInstructionsP, "mode"), "loop_cut")){
|
|
if(strSame(strGetArgumentString(a->ExtraInstructionsP, "mode"), "loop_cut")){
|
|
se->IsLoop=1; SelectMode=LA_CANVAS_SELECT_MODE_EDGES; }
|
|
se->IsLoop=1; SelectMode=LA_CANVAS_SELECT_MODE_EDGES; }
|
|
- la_PopulateSelectDataPrimitives(sd,mo,c,SelectMode);
|
|
|
|
|
|
+ la_PopulateSelectDataPrimitives(sd,mo,c,SelectMode,ex->SelectThrough);
|
|
|
|
|
|
if(se->IsLoop){ strSafePrint(&a->RuntimeHint,"◧ Cut ◨ Cancel"); }
|
|
if(se->IsLoop){ strSafePrint(&a->RuntimeHint,"◧ Cut ◨ Cancel"); }
|
|
else{ strSafePrint(&a->RuntimeHint,"◧ Place Cut ◨ Cancel ⮨ Confirm"); }
|
|
else{ strSafePrint(&a->RuntimeHint,"◧ Place Cut ◨ Cancel ⮨ Confirm"); }
|
|
@@ -1427,7 +1438,7 @@ int OPMOD_Knife(laOperator *a, laEvent *e){
|
|
int changed=0;
|
|
int changed=0;
|
|
|
|
|
|
if(e->Type==LA_R_MOUSE_DOWN || (e->Type == LA_KEY_DOWN && e->key==LA_KEY_ESCAPE)){
|
|
if(e->Type==LA_R_MOUSE_DOWN || (e->Type == LA_KEY_DOWN && e->key==LA_KEY_ESCAPE)){
|
|
- la_KnifeFinish(se,root); laNotifyUsers("tns.world"); return LA_FINISHED;
|
|
|
|
|
|
+ la_KnifeFinish(se,mo); laNotifyUsers("tns.world"); return LA_FINISHED;
|
|
}
|
|
}
|
|
|
|
|
|
if(e->Type&LA_MOUSE_EVENT){
|
|
if(e->Type&LA_MOUSE_EVENT){
|
|
@@ -1451,7 +1462,7 @@ int OPMOD_Knife(laOperator *a, laEvent *e){
|
|
tnsInvalidateMeshBatch(mo); laNotifyUsers("tns.world");
|
|
tnsInvalidateMeshBatch(mo); laNotifyUsers("tns.world");
|
|
laRecordAndPush(0,"tns.world",se->IsLoop?"Loop Cut":"Knife Cut",TNS_HINT_GEOMETRY);
|
|
laRecordAndPush(0,"tns.world",se->IsLoop?"Loop Cut":"Knife Cut",TNS_HINT_GEOMETRY);
|
|
}
|
|
}
|
|
- la_KnifeFinish(se,root); return LA_FINISHED;
|
|
|
|
|
|
+ la_KnifeFinish(se,mo); return LA_FINISHED;
|
|
}
|
|
}
|
|
|
|
|
|
if(changed){
|
|
if(changed){
|