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:
2006-03-27 08:25:06 +00:00
parent af9573e9ea
commit 0e8e848588
4 changed files with 130 additions and 104 deletions

View File

@@ -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) {