Seperated out some functionality into 3 new functions.
EM_editselection_center EM_editselection_normal EM_editselection_plane These functions are used by the manipulator to get data from an editselection. regardless of weather its a face/edge/vert.
This commit is contained in:
@@ -136,6 +136,124 @@ static void EM_strip_selections(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* generic way to get data from an EditSelection type
|
||||
These functions were written to be used by the Modifier widget when in Rotate about active mode,
|
||||
but can be used anywhere.
|
||||
EM_editselection_center
|
||||
EM_editselection_normal
|
||||
EM_editselection_plane
|
||||
*/
|
||||
void EM_editselection_center(float *center, EditSelection *ese)
|
||||
{
|
||||
if (ese->type==EDITVERT) {
|
||||
EditVert *eve= ese->data;
|
||||
VecCopyf(center, eve->co);
|
||||
} else if (ese->type==EDITEDGE) {
|
||||
EditEdge *eed= ese->data;
|
||||
VecAddf(center, eed->v1->co, eed->v2->co);
|
||||
VecMulf(center, 0.5);
|
||||
} else if (ese->type==EDITFACE) {
|
||||
EditFace *efa= ese->data;
|
||||
VecCopyf(center, efa->cent);
|
||||
}
|
||||
}
|
||||
|
||||
void EM_editselection_normal(float *normal, EditSelection *ese)
|
||||
{
|
||||
if (ese->type==EDITVERT) {
|
||||
EditVert *eve= ese->data;
|
||||
VecCopyf(normal, eve->no);
|
||||
} else if (ese->type==EDITEDGE) {
|
||||
EditEdge *eed= ese->data;
|
||||
float plane[3]; /* need a plane to correct the normal */
|
||||
float vec[3]; /* temp vec storage */
|
||||
|
||||
VecAddf(normal, eed->v1->no, eed->v2->no);
|
||||
VecSubf(plane, eed->v2->co, eed->v1->co);
|
||||
|
||||
/* the 2 vertex normals will be close but not at rightangles to the edge
|
||||
for rotate about edge we want them to be at right angles, so we need to
|
||||
do some extra colculation to correct the vert normals,
|
||||
we need the plane for this */
|
||||
Crossf(vec, normal, plane);
|
||||
Crossf(normal, plane, vec);
|
||||
Normalise(normal);
|
||||
|
||||
} else if (ese->type==EDITFACE) {
|
||||
EditFace *efa= ese->data;
|
||||
VecCopyf(normal, efa->n);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate a plane that is rightangles to the edge/vert/faces normal
|
||||
also make the plane run allong an axis that is related to the geometry,
|
||||
because this is used for the manipulators Y axis.*/
|
||||
void EM_editselection_plane(float *plane, EditSelection *ese)
|
||||
{
|
||||
if (ese->type==EDITVERT) {
|
||||
EditVert *eve= ese->data;
|
||||
float vec[3]={0,0,0};
|
||||
|
||||
if (ese->prev) { /*use previously selected data to make a usefull vertex plane */
|
||||
EM_editselection_center(vec, ese->prev);
|
||||
VecSubf(plane, eve->co, vec);
|
||||
} else {
|
||||
/* make a fake plane thats at rightangles to the normal
|
||||
we cant make a crossvec from a vec thats the same as the vec
|
||||
unlikely but possible, so make sure if the normal is (0,0,1)
|
||||
that vec isnt the same or in the same direction even.*/
|
||||
if (eve->no[0]<0.5) vec[0]=1;
|
||||
else if (eve->no[1]<0.5) vec[1]=1;
|
||||
else vec[2]=1;
|
||||
Crossf(plane, eve->no, vec);
|
||||
}
|
||||
} else if (ese->type==EDITEDGE) {
|
||||
EditEdge *eed= ese->data;
|
||||
|
||||
/*the plane is simple, it runs allong the edge
|
||||
however selecting different edges can swap the direction of the y axis.
|
||||
this makes it less likely for the y axis of the manipulator
|
||||
(running along the edge).. to flip less often.
|
||||
at least its more pradictable */
|
||||
if (eed->v2->co[1] > eed->v1->co[1]) /*check which to do first */
|
||||
VecSubf(plane, eed->v2->co, eed->v1->co);
|
||||
else
|
||||
VecSubf(plane, eed->v1->co, eed->v2->co);
|
||||
|
||||
} else if (ese->type==EDITFACE) {
|
||||
EditFace *efa= ese->data;
|
||||
float vec[3];
|
||||
if (efa->v4) { /*if its a quad- set the plane along the 2 longest edges.*/
|
||||
float vecA[3], vecB[3];
|
||||
VecSubf(vecA, efa->v4->co, efa->v3->co);
|
||||
VecSubf(vecB, efa->v1->co, efa->v2->co);
|
||||
VecAddf(plane, vecA, vecB);
|
||||
|
||||
VecSubf(vecA, efa->v1->co, efa->v4->co);
|
||||
VecSubf(vecB, efa->v2->co, efa->v3->co);
|
||||
VecAddf(vec, vecA, vecB);
|
||||
/*use the biggest edge length*/
|
||||
if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
|
||||
VecCopyf(plane, vec);
|
||||
} else {
|
||||
/*start with v1-2 */
|
||||
VecSubf(plane, efa->v1->co, efa->v2->co);
|
||||
|
||||
/*test the edge between v2-3, use if longer */
|
||||
VecSubf(vec, efa->v2->co, efa->v3->co);
|
||||
if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
|
||||
VecCopyf(plane, vec);
|
||||
|
||||
/*test the edge between v1-3, use if longer */
|
||||
VecSubf(vec, efa->v3->co, efa->v1->co);
|
||||
if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
|
||||
VecCopyf(plane, vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EM_select_face(EditFace *efa, int sel)
|
||||
{
|
||||
if(sel) {
|
||||
|
||||
Reference in New Issue
Block a user