gooseberry request:

Attempt to select closest bones when possible.

Occlusion query selection does't support this well because we can't
really derive depth information from occlusion tests. May be possible to
improve this somewhat in the future.
This commit is contained in:
Antony Riakiotakis 2014-09-24 18:02:40 +02:00
parent 345b16601c
commit fc3753b8f6
6 changed files with 31 additions and 15 deletions

@ -237,7 +237,7 @@ void armature_select_mirrored(struct bArmature *arm);
void armature_tag_unselect(struct bArmature *arm);
void *get_nearest_bone(struct bContext *C, short findunsel, int x, int y);
void *get_bone_from_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer, short hits, short findunsel);
void *get_bone_from_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer, short hits, short findunsel, bool do_nearest);
int bone_looper(struct Object *ob, struct Bone *bone, void *data,
int (*bone_func)(struct Object *, struct Bone *, void *));

@ -73,7 +73,7 @@ Bone *get_indexed_bone(Object *ob, int index)
/* See if there are any selected bones in this buffer */
/* only bones from base are checked on */
void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short findunsel)
void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short findunsel, bool do_nearest)
{
Object *obedit = scene->obedit; // XXX get from context
Bone *bone;
@ -82,6 +82,7 @@ void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer,
unsigned int hitresult;
short i;
bool takeNext = false;
int minsel = 0xffffffff, minunsel = 0xffffffff;
for (i = 0; i < hits; i++) {
hitresult = buffer[3 + (i * 4)];
@ -102,7 +103,7 @@ void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer,
else
sel = !(bone->flag & BONE_SELECTED);
data = bone;
data = bone;
}
else {
data = NULL;
@ -123,14 +124,29 @@ void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer,
if (data) {
if (sel) {
if (!firstSel) firstSel = data;
takeNext = 1;
if (do_nearest) {
if (minsel > buffer[4 * i + 1]) {
firstSel = bone;
minsel = buffer[4 * i + 1];
}
}
else {
if (!firstSel) firstSel = data;
takeNext = 1;
}
}
else {
if (!firstunSel)
firstunSel = data;
if (takeNext)
return data;
if (do_nearest) {
if (minunsel > buffer[4 * i + 1]) {
firstunSel = bone;
minunsel = buffer[4 * i + 1];
}
}
else
{
if (!firstunSel) firstunSel = data;
if (takeNext) return data;
}
}
}
}
@ -163,7 +179,7 @@ void *get_nearest_bone(bContext *C, short findunsel, int x, int y)
hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);
if (hits > 0)
return get_bone_from_selectbuffer(vc.scene, vc.scene->basact, buffer, hits, findunsel);
return get_bone_from_selectbuffer(vc.scene, vc.scene->basact, buffer, hits, findunsel, true);
return NULL;
}

@ -133,14 +133,14 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
/* called from editview.c, for mode-less pose selection */
/* assumes scene obact and basact is still on old situation */
int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits,
bool extend, bool deselect, bool toggle)
bool extend, bool deselect, bool toggle, bool do_nearest)
{
Object *ob = base->object;
Bone *nearBone;
if (!ob || !ob->pose) return 0;
nearBone = get_bone_from_selectbuffer(scene, base, buffer, hits, 1);
nearBone = get_bone_from_selectbuffer(scene, base, buffer, hits, 1, do_nearest);
/* if the bone cannot be affected, don't do anything */
if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {

@ -123,7 +123,7 @@ void ED_armature_deselect_all(struct Object *obedit, int toggle);
void ED_armature_deselect_all_visible(struct Object *obedit);
int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer,
short hits, bool extend, bool deselect, bool toggle);
short hits, bool extend, bool deselect, bool toggle, bool do_nearest);
bool mouse_armature(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
int join_armature_exec(struct bContext *C, struct wmOperator *op);
struct Bone *get_indexed_bone(struct Object *ob, int index);

@ -1522,7 +1522,7 @@ static bool mouse_select(bContext *C, const int mval[2],
}
}
}
else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) {
else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle, do_nearest)) {
/* then bone is found */
/* we make the armature selected:

@ -127,7 +127,7 @@ void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, c
}
else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthMask(GL_FALSE);
glDepthFunc(GL_EQUAL);
}
}