Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2008-12-19 20:14:02 +0300
committerTon Roosendaal <ton@blender.org>2008-12-19 20:14:02 +0300
commit663612c70c0e41be59f918a45eaa93164626f0a5 (patch)
treecb6c3844d30f8f9577b18de66f5e9d9385e7c558 /source/blender/editors/space_view3d
parent92b1d3f9461e6d122d6523955cc8124559e5f36e (diff)
2.5
View3d: middle mouse rotate, translate, zoom. (using default mouse map)
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r--source/blender/editors/space_view3d/Makefile1
-rw-r--r--source/blender/editors/space_view3d/SConscript2
-rw-r--r--source/blender/editors/space_view3d/drawobject.c76
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c1174
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h10
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c77
7 files changed, 730 insertions, 630 deletions
diff --git a/source/blender/editors/space_view3d/Makefile b/source/blender/editors/space_view3d/Makefile
index 7a5f609a187..442ab502e65 100644
--- a/source/blender/editors/space_view3d/Makefile
+++ b/source/blender/editors/space_view3d/Makefile
@@ -49,6 +49,7 @@ CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../python
CPPFLAGS += -I../../gpu
+CPPFLAGS += -I../../makesrna
CPPFLAGS += -I../../render/extern/include
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript
index 77cf03820ed..fac4cd65ee2 100644
--- a/source/blender/editors/space_view3d/SConscript
+++ b/source/blender/editors/space_view3d/SConscript
@@ -6,6 +6,6 @@ sources = env.Glob('*.c')
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../render/extern/include #/intern/guardedalloc #intern/bmfont'
-incs += ' ../../gpu'
+incs += ' ../../gpu ../../makesrna'
env.BlenderLib ( 'bf_editors_space_view3d', sources, Split(incs), [], libtype=['core','intern'], priority=[35, 40] )
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 4c621c6ec63..01bdc1ba941 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -1202,30 +1202,30 @@ static void drawlattice(View3D *v3d, Object *ob)
static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
- struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
- ARegion *ar= NULL; // XXX
- View3D *v3d= NULL; // XXX
+ struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ARegion *ar; View3D *v3d; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
EditVert *eve = EM_get_vert_for_index(index);
short s[2];
if (eve->h==0) {
if (data->clipVerts) {
- view3d_project_short_clip(ar, v3d, co, s, data->pmat, data->vmat);
+ view3d_project_short_clip(data->ar, data->v3d, co, s, data->pmat, data->vmat);
} else {
- view3d_project_short_noclip(ar, co, s, data->pmat);
+ view3d_project_short_noclip(data->ar, co, s, data->pmat);
}
data->func(data->userData, eve, s[0], s[1], index);
}
}
-void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
+
+void mesh_foreachScreenVert(ARegion *ar, View3D *v3d, void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
{
- struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
- View3D *v3d= NULL; // XXX
+ struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ARegion *ar; View3D *v3d; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
data.func = func;
data.userData = userData;
+ data.ar= ar;
+ data.v3d= v3d;
data.clipVerts = clipVerts;
view3d_get_object_project_mat(v3d, G.obedit, data.pmat, data.vmat);
@@ -1239,23 +1239,21 @@ void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, i
static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
{
- struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
- ARegion *ar= NULL; // XXX
- View3D *v3d= NULL; // XXX
+ struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ARegion *ar; View3D *v3d; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
EditEdge *eed = EM_get_edge_for_index(index);
short s[2][2];
if (eed->h==0) {
if (data->clipVerts==1) {
- view3d_project_short_clip(ar, v3d, v0co, s[0], data->pmat, data->vmat);
- view3d_project_short_clip(ar, v3d, v1co, s[1], data->pmat, data->vmat);
+ view3d_project_short_clip(data->ar, data->v3d, v0co, s[0], data->pmat, data->vmat);
+ view3d_project_short_clip(data->ar, data->v3d, v1co, s[1], data->pmat, data->vmat);
} else {
- view3d_project_short_noclip(ar, v0co, s[0], data->pmat);
- view3d_project_short_noclip(ar, v1co, s[1], data->pmat);
+ view3d_project_short_noclip(data->ar, v0co, s[0], data->pmat);
+ view3d_project_short_noclip(data->ar, v1co, s[1], data->pmat);
if (data->clipVerts==2) {
- if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<ar->winx && s[0][1]<ar->winy))
- if (!(s[1][0]>=0 && s[1][1]>= 0 && s[1][0]<ar->winx && s[1][1]<ar->winy))
+ if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<data->ar->winx && s[0][1]<data->ar->winy))
+ if (!(s[1][0]>=0 && s[1][1]>= 0 && s[1][0]<data->ar->winx && s[1][1]<data->ar->winy))
return;
}
}
@@ -1263,13 +1261,14 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0
data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], index);
}
}
-void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
+void mesh_foreachScreenEdge(ARegion *ar, View3D *v3d, void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
{
- struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
- View3D *v3d= NULL; // XXX
+ struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ARegion *ar; View3D *v3d; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
data.func = func;
+ data.ar= ar;
+ data.v3d= v3d;
data.userData = userData;
data.clipVerts = clipVerts;
@@ -1284,25 +1283,24 @@ void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0,
static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *no)
{
- struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float pmat[4][4], vmat[4][4]; } *data = userData;
- ARegion *ar= NULL; // XXX
- View3D *v3d= NULL; // XXX
+ struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ARegion *ar; View3D *v3d; float pmat[4][4], vmat[4][4]; } *data = userData;
EditFace *efa = EM_get_face_for_index(index);
short s[2];
if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
- view3d_project_short_clip(ar, v3d, cent, s, data->pmat, data->vmat);
+ view3d_project_short_clip(data->ar, data->v3d, cent, s, data->pmat, data->vmat);
data->func(data->userData, efa, s[0], s[1], index);
}
}
-void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData)
+void mesh_foreachScreenFace(ARegion *ar, View3D *v3d, void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData)
{
- struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float pmat[4][4], vmat[4][4]; } data;
+ struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ARegion *ar; View3D *v3d; float pmat[4][4], vmat[4][4]; } data;
DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
- View3D *v3d= NULL; // XXX
data.func = func;
+ data.ar= ar;
+ data.v3d= v3d;
data.userData = userData;
view3d_get_object_project_mat(v3d, G.obedit, data.pmat, data.vmat);
@@ -1314,10 +1312,8 @@ void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, i
dm->release(dm);
}
-void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), void *userData)
+void nurbs_foreachScreenVert(ARegion *ar, View3D *v3d, void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), void *userData)
{
- ARegion *ar= NULL; // XXX
- View3D *v3d= NULL; // XXX
float pmat[4][4], vmat[4][4];
short s[2];
Nurb *nu;
@@ -1375,7 +1371,7 @@ void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp,
static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
{
- Scene *scene= NULL; // XXX
+ Scene *scene= (Scene *)userData;
EditFace *efa = EM_get_face_for_index(index);
if (efa->h==0 && efa->fgonf!=EM_FGON) {
@@ -1385,9 +1381,10 @@ static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent
cent[2] + no[2]*scene->editbutsize);
}
}
-static void draw_dm_face_normals(DerivedMesh *dm) {
+static void draw_dm_face_normals(Scene *scene, DerivedMesh *dm)
+{
glBegin(GL_LINES);
- dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, 0);
+ dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, scene);
glEnd();
}
@@ -1409,7 +1406,7 @@ static void draw_dm_face_centers(DerivedMesh *dm, int sel)
static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
- Scene *scene= NULL; // XXX
+ Scene *scene= (Scene *)userData;
EditVert *eve = EM_get_vert_for_index(index);
if (eve->h==0) {
@@ -1426,9 +1423,10 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co,
}
}
}
-static void draw_dm_vert_normals(DerivedMesh *dm) {
+static void draw_dm_vert_normals(Scene *scene, DerivedMesh *dm)
+{
glBegin(GL_LINES);
- dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, NULL);
+ dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, scene);
glEnd();
}
@@ -2106,11 +2104,11 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, Object *ob, EditMesh *em, D
if(G.f & G_DRAWNORMALS) {
UI_ThemeColor(TH_NORMAL);
- draw_dm_face_normals(cageDM);
+ draw_dm_face_normals(scene, cageDM);
}
if(G.f & G_DRAW_VNORMALS) {
UI_ThemeColor(TH_NORMAL);
- draw_dm_vert_normals(cageDM);
+ draw_dm_vert_normals(scene, cageDM);
}
if(G.f & (G_DRAW_EDGELEN|G_DRAW_FACEAREA|G_DRAW_EDGEANG))
@@ -2978,7 +2976,7 @@ static void draw_new_particle_system(View3D *v3d, Base *base, ParticleSystem *ps
break;
case PART_DRAW_BB:
if(v3d->camera==0 && part->bb_ob==0){
-// XXX error("Billboards need an active camera or a target object!");
+ printf("Billboards need an active camera or a target object!\n");
draw_as=part->draw_as=PART_DRAW_DOT;
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index b279e888bea..e20490c0c07 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -178,14 +178,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
return (SpaceLink *)v3dn;
}
-void view3d_operatortypes(void)
-{
-}
-
-void view3d_keymap(struct wmWindowManager *wm)
-{
-}
-
static void view3d_main_area_draw(const bContext *C, ARegion *ar)
{
/* draw entirely, view changes should be handled here */
@@ -195,6 +187,17 @@ static void view3d_main_area_draw(const bContext *C, ARegion *ar)
drawview3dspace(CTX_data_scene(C), ar, v3d);
}
+/* add handlers, stuff you only do once or on area/region changes */
+static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
+{
+ ListBase *keymap;
+
+ /* own keymap */
+ keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0); /* XXX weak? */
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap,NULL, NULL);
+
+}
+
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar)
@@ -244,6 +247,7 @@ void ED_spacetype_view3d(void)
art= MEM_callocN(sizeof(ARegionType), "spacetype time region");
art->regionid = RGN_TYPE_WINDOW;
art->draw= view3d_main_area_draw;
+ art->init= view3d_main_area_init;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index aa2f58ba4a2..2cca530ce86 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -49,6 +49,7 @@
#include "BLI_rand.h"
#include "BKE_action.h"
+#include "BKE_context.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_scene.h"
@@ -61,39 +62,49 @@
#include "BIF_retopo.h"
#include "WM_api.h"
+#include "WM_types.h"
#include "ED_screen.h"
+#include "ED_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "ED_types.h"
-
#include "PIL_time.h" /* smoothview */
#include "view3d_intern.h" // own include
/* ********************** view3d_edit: view manipulations ********************* */
-#define TRACKBALLSIZE (1.1)
+/* ************************** init for view ops **********************************/
-/* the central math in this function was copied from trackball.cpp, sample code from the
- Developers Toolbox series by SGI. */
+typedef struct ViewOpsData {
+ ARegion *ar;
+ View3D *v3d;
+
+ float oldquat[4];
+ float trackvec[3];
+ float ofs[3], obofs[3];
+ float reverse, dist0;
+
+ int origx, origy, oldx, oldy;
+
+} ViewOpsData;
-/* trackball: better one than a full spherical solution */
+#define TRACKBALLSIZE (1.1)
-void calctrackballvecfirst(rcti *area, short *mval, float *vec)
+static void calctrackballvec(rcti *rect, int mx, int my, float *vec)
{
float x, y, radius, d, z, t;
radius= TRACKBALLSIZE;
/* normalize x and y */
- x= (area->xmax + area->xmin)/2 -mval[0];
- x/= (float)((area->xmax - area->xmin)/2);
- y= (area->ymax + area->ymin)/2 -mval[1];
- y/= (float)((area->ymax - area->ymin)/2);
+ x= (rect->xmax + rect->xmin)/2 - mx;
+ x/= (float)((rect->xmax - rect->xmin)/4);
+ y= (rect->ymax + rect->ymin)/2 - my;
+ y/= (float)((rect->ymax - rect->ymin)/2);
d = sqrt(x*x + y*y);
if (d < radius*M_SQRT1_2) /* Inside sphere */
@@ -107,52 +118,592 @@ void calctrackballvecfirst(rcti *area, short *mval, float *vec)
vec[0]= x;
vec[1]= y;
vec[2]= -z; /* yah yah! */
+}
+
- if( fabs(vec[2])>fabs(vec[1]) && fabs(vec[2])>fabs(vec[0]) ) {
- vec[0]= 0.0;
- vec[1]= 0.0;
- if(vec[2]>0.0) vec[2]= 1.0; else vec[2]= -1.0;
+static void viewops_data(bContext *C, wmOperator *op, wmEvent *event)
+{
+ ScrArea *sa= CTX_wm_area(C);
+ View3D *v3d= sa->spacedata.first;
+ ViewOpsData *vod= MEM_callocN(sizeof(ViewOpsData), "viewops data");
+
+ /* store data */
+ op->customdata= vod;
+ vod->ar= CTX_wm_region(C);
+ vod->v3d= v3d;
+ vod->dist0= v3d->dist;
+ QUATCOPY(vod->oldquat, v3d->viewquat);
+ vod->origx= vod->oldx= event->x;
+ vod->origy= vod->oldy= event->y;
+
+ calctrackballvec(&vod->ar->winrct, event->x, event->y, vod->trackvec);
+
+ initgrabz(v3d, -v3d->ofs[0], -v3d->ofs[1], -v3d->ofs[2]);
+
+ vod->reverse= 1.0f;
+ if (v3d->persmat[2][1] < 0.0f)
+ vod->reverse= -1.0f;
+
+}
+
+/* ************************** viewrotate **********************************/
+
+static const float thres = 0.93f; //cos(20 deg);
+
+#define COS45 0.70710678118654746
+#define SIN45 COS45
+
+static float snapquats[39][6] = {
+ /*{q0, q1, q3, q4, view, oposite_direction}*/
+{COS45, -SIN45, 0.0, 0.0, 1, 0}, //front
+{0.0, 0.0, -SIN45, -SIN45, 1, 1}, //back
+{1.0, 0.0, 0.0, 0.0, 7, 0}, //top
+{0.0, -1.0, 0.0, 0.0, 7, 1}, //bottom
+{0.5, -0.5, -0.5, -0.5, 3, 0}, //left
+{0.5, -0.5, 0.5, 0.5, 3, 1}, //right
+
+ /* some more 45 deg snaps */
+{0.65328145027160645, -0.65328145027160645, 0.27059805393218994, 0.27059805393218994, 0, 0},
+{0.92387950420379639, 0.0, 0.0, 0.38268342614173889, 0, 0},
+{0.0, -0.92387950420379639, 0.38268342614173889, 0.0, 0, 0},
+{0.35355335474014282, -0.85355335474014282, 0.35355338454246521, 0.14644660055637360, 0, 0},
+{0.85355335474014282, -0.35355335474014282, 0.14644660055637360, 0.35355338454246521, 0, 0},
+{0.49999994039535522, -0.49999994039535522, 0.49999997019767761, 0.49999997019767761, 0, 0},
+{0.27059802412986755, -0.65328145027160645, 0.65328145027160645, 0.27059802412986755, 0, 0},
+{0.65328145027160645, -0.27059802412986755, 0.27059802412986755, 0.65328145027160645, 0, 0},
+{0.27059799432754517, -0.27059799432754517, 0.65328139066696167, 0.65328139066696167, 0, 0},
+{0.38268336653709412, 0.0, 0.0, 0.92387944459915161, 0, 0},
+{0.0, -0.38268336653709412, 0.92387944459915161, 0.0, 0, 0},
+{0.14644658565521240, -0.35355335474014282, 0.85355335474014282, 0.35355335474014282, 0, 0},
+{0.35355335474014282, -0.14644658565521240, 0.35355335474014282, 0.85355335474014282, 0, 0},
+{0.0, 0.0, 0.92387944459915161, 0.38268336653709412, 0, 0},
+{-0.0, 0.0, 0.38268336653709412, 0.92387944459915161, 0, 0},
+{-0.27059802412986755, 0.27059802412986755, 0.65328133106231689, 0.65328133106231689, 0, 0},
+{-0.38268339633941650, 0.0, 0.0, 0.92387938499450684, 0, 0},
+{0.0, 0.38268339633941650, 0.92387938499450684, 0.0, 0, 0},
+{-0.14644658565521240, 0.35355338454246521, 0.85355329513549805, 0.35355332493782043, 0, 0},
+{-0.35355338454246521, 0.14644658565521240, 0.35355332493782043, 0.85355329513549805, 0, 0},
+{-0.49999991059303284, 0.49999991059303284, 0.49999985098838806, 0.49999985098838806, 0, 0},
+{-0.27059799432754517, 0.65328145027160645, 0.65328139066696167, 0.27059799432754517, 0, 0},
+{-0.65328145027160645, 0.27059799432754517, 0.27059799432754517, 0.65328139066696167, 0, 0},
+{-0.65328133106231689, 0.65328133106231689, 0.27059793472290039, 0.27059793472290039, 0, 0},
+{-0.92387932538986206, 0.0, 0.0, 0.38268333673477173, 0, 0},
+{0.0, 0.92387932538986206, 0.38268333673477173, 0.0, 0, 0},
+{-0.35355329513549805, 0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0, 0},
+{-0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0.35355329513549805, 0, 0},
+{-0.38268330693244934, 0.92387938499450684, 0.0, 0.0, 0, 0},
+{-0.92387938499450684, 0.38268330693244934, 0.0, 0.0, 0, 0},
+{-COS45, 0.0, 0.0, SIN45, 0, 0},
+{COS45, 0.0, 0.0, SIN45, 0, 0},
+{0.0, 0.0, 0.0, 1.0, 0, 0}
+};
+
+
+static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl)
+{
+ View3D *v3d= vod->v3d;
+ int use_sel= 0; /* XXX */
+
+ v3d->view= 0; /* need to reset everytime because of view snapping */
+
+ if (U.flag & USER_TRACKBALL) {
+ float phi, si, q1[4], dvec[3], newvec[3];
+
+ calctrackballvec(&vod->ar->winrct, x, y, newvec);
+
+ VecSubf(dvec, newvec, vod->trackvec);
+
+ si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]);
+ si/= (2.0*TRACKBALLSIZE);
+
+ Crossf(q1+1, vod->trackvec, newvec);
+ Normalize(q1+1);
+
+ /* Allow for rotation beyond the interval
+ * [-pi, pi] */
+ while (si > 1.0)
+ si -= 2.0;
+
+ /* This relation is used instead of
+ * phi = asin(si) so that the angle
+ * of rotation is linearly proportional
+ * to the distance that the mouse is
+ * dragged. */
+ phi = si * M_PI / 2.0;
+
+ si= sin(phi);
+ q1[0]= cos(phi);
+ q1[1]*= si;
+ q1[2]*= si;
+ q1[3]*= si;
+ QuatMul(v3d->viewquat, q1, vod->oldquat);
+
+ if (use_sel) {
+ /* compute the post multiplication quat, to rotate the offset correctly */
+ QUATCOPY(q1, vod->oldquat);
+ QuatConj(q1);
+ QuatMul(q1, q1, v3d->viewquat);
+
+ QuatConj(q1); /* conj == inv for unit quat */
+ VECCOPY(v3d->ofs, vod->ofs);
+ VecSubf(v3d->ofs, v3d->ofs, vod->obofs);
+ QuatMulVecf(q1, v3d->ofs);
+ VecAddf(v3d->ofs, v3d->ofs, vod->obofs);
+ }
+ }
+ else {
+ /* New turntable view code by John Aughey */
+ float si, phi, q1[4];
+ float m[3][3];
+ float m_inv[3][3];
+ float xvec[3] = {1,0,0};
+ /* Sensitivity will control how fast the viewport rotates. 0.0035 was
+ obtained experimentally by looking at viewport rotation sensitivities
+ on other modeling programs. */
+ /* Perhaps this should be a configurable user parameter. */
+ const float sensitivity = 0.0035;
+
+ /* Get the 3x3 matrix and its inverse from the quaternion */
+ QuatToMat3(v3d->viewquat, m);
+ Mat3Inv(m_inv,m);
+
+ /* Determine the direction of the x vector (for rotating up and down) */
+ /* This can likely be compuated directly from the quaternion. */
+ Mat3MulVecfl(m_inv,xvec);
+
+ /* Perform the up/down rotation */
+ phi = sensitivity * -(y - vod->oldy);
+ si = sin(phi);
+ q1[0] = cos(phi);
+ q1[1] = si * xvec[0];
+ q1[2] = si * xvec[1];
+ q1[3] = si * xvec[2];
+ QuatMul(v3d->viewquat, v3d->viewquat, q1);
+
+ if (use_sel) {
+ QuatConj(q1); /* conj == inv for unit quat */
+ VecSubf(v3d->ofs, v3d->ofs, vod->obofs);
+ QuatMulVecf(q1, v3d->ofs);
+ VecAddf(v3d->ofs, v3d->ofs, vod->obofs);
+ }
+
+ /* Perform the orbital rotation */
+ phi = sensitivity * vod->reverse * (x - vod->oldx);
+ q1[0] = cos(phi);
+ q1[1] = q1[2] = 0.0;
+ q1[3] = sin(phi);
+ QuatMul(v3d->viewquat, v3d->viewquat, q1);
+
+ if (use_sel) {
+ QuatConj(q1);
+ VecSubf(v3d->ofs, v3d->ofs, vod->obofs);
+ QuatMulVecf(q1, v3d->ofs);
+ VecAddf(v3d->ofs, v3d->ofs, vod->obofs);
+ }
+ }
+
+ /* check for view snap */
+ if (ctrl){
+ int i;
+ float viewmat[3][3];
+
+
+ QuatToMat3(v3d->viewquat, viewmat);
+
+ for (i = 0 ; i < 39; i++){
+ float snapmat[3][3];
+ float view = (int)snapquats[i][4];
+ float oposite_dir = (int)snapquats[i][5];
+
+ QuatToMat3(snapquats[i], snapmat);
+
+ if ((Inpf(snapmat[0], viewmat[0]) > thres) &&
+ (Inpf(snapmat[1], viewmat[1]) > thres) &&
+ (Inpf(snapmat[2], viewmat[2]) > thres)){
+
+ QUATCOPY(v3d->viewquat, snapquats[i]);
+
+ v3d->view = view;
+ if (view){
+ if (oposite_dir){
+ v3d->flag2 |= V3D_OPP_DIRECTION_NAME;
+ }else{
+ v3d->flag2 &= ~V3D_OPP_DIRECTION_NAME;
+ }
+ }
+
+ break;
+ }
+ }
}
- else if( fabs(vec[1])>fabs(vec[0]) && fabs(vec[1])>fabs(vec[2]) ) {
- vec[0]= 0.0;
- vec[2]= 0.0;
- if(vec[1]>0.0) vec[1]= 1.0; else vec[1]= -1.0;
+ vod->oldx= x;
+ vod->oldy= y;
+
+ ED_region_tag_redraw(vod->ar);
+}
+
+static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+
+ /* execute the events */
+ switch(event->type) {
+ case MOUSEMOVE:
+ viewrotate_apply(op->customdata, event->x, event->y, event->ctrl);
+ break;
+
+ case MIDDLEMOUSE:
+ if(event->val==0) {
+
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+
+ return OPERATOR_FINISHED;
+ }
+ break;
}
- else {
- vec[1]= 0.0;
- vec[2]= 0.0;
- if(vec[0]>0.0) vec[0]= 1.0; else vec[0]= -1.0;
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ ViewOpsData *vod;
+
+ /* makes op->customdata */
+ viewops_data(C, op, event);
+ vod= op->customdata;
+
+ /* switch from camera view when: */
+ if(vod->v3d->persp != V3D_PERSP) {
+
+ if (U.uiflag & USER_AUTOPERSP)
+ vod->v3d->persp= V3D_PERSP;
+ else if(vod->v3d->persp==V3D_CAMOB)
+ vod->v3d->persp= V3D_PERSP;
+ ED_region_tag_redraw(vod->ar);
}
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
}
-void calctrackballvec(rcti *area, short *mval, float *vec)
+
+void ED_VIEW3D_OT_viewrotate(wmOperatorType *ot)
{
- float x, y, radius, d, z, t;
- radius= TRACKBALLSIZE;
+ /* identifiers */
+ ot->name= "Rotate view";
+ ot->idname= "ED_VIEW3D_OT_viewrotate";
+
+ /* api callbacks */
+ ot->invoke= viewrotate_invoke;
+ ot->modal= viewrotate_modal;
+}
+
+/* ************************ viewmove ******************************** */
+
+static void viewmove_apply(ViewOpsData *vod, int x, int y)
+{
+ if(vod->v3d->persp==V3D_CAMOB) {
+ float max= (float)MAX2(vod->ar->winx, vod->ar->winy);
+
+ vod->v3d->camdx += (vod->oldx - x)/(max);
+ vod->v3d->camdy += (vod->oldy - y)/(max);
+ CLAMP(vod->v3d->camdx, -1.0f, 1.0f);
+ CLAMP(vod->v3d->camdy, -1.0f, 1.0f);
+// XXX preview3d_event= 0;
+ }
+ else {
+ float dvec[3];
+
+ window_to_3d(vod->ar, vod->v3d, dvec, x-vod->oldx, y-vod->oldy);
+ VecAddf(vod->v3d->ofs, vod->v3d->ofs, dvec);
+ }
- /* x en y normalizeren */
- x= (area->xmax + area->xmin)/2 -mval[0];
- x/= (float)((area->xmax - area->xmin)/4);
- y= (area->ymax + area->ymin)/2 -mval[1];
- y/= (float)((area->ymax - area->ymin)/2);
+ vod->oldx= x;
+ vod->oldy= y;
- d = sqrt(x*x + y*y);
- if (d < radius*M_SQRT1_2) /* Inside sphere */
- z = sqrt(radius*radius - d*d);
- else
- { /* On hyperbola */
- t = radius / M_SQRT2;
- z = t*t / d;
+ ED_region_tag_redraw(vod->ar);
+}
+
+
+static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* execute the events */
+ switch(event->type) {
+ case MOUSEMOVE:
+ viewmove_apply(op->customdata, event->x, event->y);
+ break;
+
+ case MIDDLEMOUSE:
+ if(event->val==0) {
+
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+
+ return OPERATOR_FINISHED;
+ }
+ break;
}
+
+ return OPERATOR_RUNNING_MODAL;
+}
- vec[0]= x;
- vec[1]= y;
- vec[2]= -z; /* yah yah! */
+static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* makes op->customdata */
+ viewops_data(C, op, event);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
+void ED_VIEW3D_OT_viewmove(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name= "Rotate view";
+ ot->idname= "ED_VIEW3D_OT_viewmove";
+
+ /* api callbacks */
+ ot->invoke= viewmove_invoke;
+ ot->modal= viewmove_modal;
+}
+
+/* ************************ viewzoom ******************************** */
+
+static void view_zoom_mouseloc(ARegion *ar, View3D *v3d, float dfac, int mx, int my)
+{
+ if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ float dvec[3];
+ float tvec[3];
+ float tpos[3];
+ float new_dist;
+ short vb[2], mouseloc[2];
+
+ mouseloc[0]= mx - ar->winrct.xmin;
+ mouseloc[1]= my - ar->winrct.ymin;
+
+ /* find the current window width and height */
+ vb[0] = ar->winx;
+ vb[1] = ar->winy;
+
+ tpos[0] = -v3d->ofs[0];
+ tpos[1] = -v3d->ofs[1];
+ tpos[2] = -v3d->ofs[2];
+
+ /* Project cursor position into 3D space */
+ initgrabz(v3d, tpos[0], tpos[1], tpos[2]);
+ window_to_3d(ar, v3d, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
+
+ /* Calculate view target position for dolly */
+ tvec[0] = -(tpos[0] + dvec[0]);
+ tvec[1] = -(tpos[1] + dvec[1]);
+ tvec[2] = -(tpos[2] + dvec[2]);
+
+ /* Offset to target position and dolly */
+ new_dist = v3d->dist * dfac;
+
+ VECCOPY(v3d->ofs, tvec);
+ v3d->dist = new_dist;
+
+ /* Calculate final offset */
+ dvec[0] = tvec[0] + dvec[0] * dfac;
+ dvec[1] = tvec[1] + dvec[1] * dfac;
+ dvec[2] = tvec[2] + dvec[2] * dfac;
+
+ VECCOPY(v3d->ofs, dvec);
+ } else {
+ v3d->dist *= dfac;
+ }
+}
+
+
+static void viewzoom_apply(ViewOpsData *vod, int x, int y)
+{
+ float zfac=1.0;
+
+ if(U.viewzoom==USER_ZOOM_CONT) {
+ // oldstyle zoom
+ zfac = 1.0+(float)(vod->origx - x + vod->origy - y)/1000.0;
+ }
+ else if(U.viewzoom==USER_ZOOM_SCALE) {
+ int ctr[2], len1, len2;
+ // method which zooms based on how far you move the mouse
+
+ ctr[0] = (vod->ar->winrct.xmax + vod->ar->winrct.xmin)/2;
+ ctr[1] = (vod->ar->winrct.ymax + vod->ar->winrct.ymin)/2;
+
+ len1 = (int)sqrt((ctr[0] - x)*(ctr[0] - x) + (ctr[1] - y)*(ctr[1] - y)) + 5;
+ len2 = (int)sqrt((ctr[0] - vod->origx)*(ctr[0] - vod->origx) + (ctr[1] - vod->origy)*(ctr[1] - vod->origy)) + 5;
+
+ zfac = vod->dist0 * ((float)len2/len1) / vod->v3d->dist;
+ }
+ else { /* USER_ZOOM_DOLLY */
+ float len1 = (vod->ar->winrct.ymax - y) + 5;
+ float len2 = (vod->ar->winrct.ymax - vod->origy) + 5;
+ zfac = vod->dist0 * (2.0*((len2/len1)-1.0) + 1.0) / vod->v3d->dist;
+ }
+
+ if(zfac != 1.0 && zfac*vod->v3d->dist > 0.001*vod->v3d->grid &&
+ zfac*vod->v3d->dist < 10.0*vod->v3d->far)
+ view_zoom_mouseloc(vod->ar, vod->v3d, zfac, vod->oldx, vod->oldy);
+
+
+ if ((U.uiflag & USER_ORBIT_ZBUF) && (U.viewzoom==USER_ZOOM_CONT) && (vod->v3d->persp==V3D_PERSP)) {
+ float upvec[3], mat[3][3];
+
+ /* Secret apricot feature, translate the view when in continues mode */
+ upvec[0] = upvec[1] = 0.0f;
+ upvec[2] = (vod->dist0 - vod->v3d->dist) * vod->v3d->grid;
+ vod->v3d->dist = vod->dist0;
+ Mat3CpyMat4(mat, vod->v3d->viewinv);
+ Mat3MulVecfl(mat, upvec);
+ VecAddf(vod->v3d->ofs, vod->v3d->ofs, upvec);
+ } else {
+ /* these limits are in toets.c too */
+ if(vod->v3d->dist<0.001*vod->v3d->grid) vod->v3d->dist= 0.001*vod->v3d->grid;
+ if(vod->v3d->dist>10.0*vod->v3d->far) vod->v3d->dist=10.0*vod->v3d->far;
+ }
+
+// XXX if(vod->v3d->persp==V3D_ORTHO || vod->v3d->persp==V3D_CAMOB) preview3d_event= 0;
+
+ ED_region_tag_redraw(vod->ar);
+}
+
+
+static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* execute the events */
+ switch(event->type) {
+ case MOUSEMOVE:
+ viewzoom_apply(op->customdata, event->x, event->y);
+ break;
+
+ case MIDDLEMOUSE:
+ if(event->val==0) {
+
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+
+ return OPERATOR_FINISHED;
+ }
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* makes op->customdata */
+ viewops_data(C, op, event);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
+void ED_VIEW3D_OT_viewzoom(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name= "Rotate view";
+ ot->idname= "ED_VIEW3D_OT_viewzoom";
+
+ /* api callbacks */
+ ot->invoke= viewzoom_invoke;
+ ot->modal= viewzoom_modal;
+}
+
+/* ************************* below the line! *********************** */
+
+
+/* XXX todo Zooms in on a border drawn by the user */
+int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mouse_worldloc[3] ) //, float *autodist )
+{
+ rcti rect;
+ /* ZBuffer depth vars */
+ bglMats mats;
+ float depth, depth_close= MAXFLOAT;
+ int had_depth = 0;
+ double cent[2], p[3];
+ int xs, ys;
+
+ // XXX getmouseco_areawin(mval);
+
+ // XXX persp(PERSP_VIEW);
+
+ rect.xmax = mval[0] + 4;
+ rect.ymax = mval[1] + 4;
+
+ rect.xmin = mval[0] - 4;
+ rect.ymin = mval[1] - 4;
+
+ /* Get Z Depths, needed for perspective, nice for ortho */
+ bgl_get_mats(&mats);
+ draw_depth(scene, ar, v3d, NULL);
+
+ /* force updating */
+ if (v3d->depths) {
+ had_depth = 1;
+ v3d->depths->damaged = 1;
+ }
+
+ view3d_update_depths(ar, v3d);
+
+ /* Constrain rect to depth bounds */
+ if (rect.xmin < 0) rect.xmin = 0;
+ if (rect.ymin < 0) rect.ymin = 0;
+ if (rect.xmax >= v3d->depths->w) rect.xmax = v3d->depths->w-1;
+ if (rect.ymax >= v3d->depths->h) rect.ymax = v3d->depths->h-1;
+
+ /* Find the closest Z pixel */
+ for (xs=rect.xmin; xs < rect.xmax; xs++) {
+ for (ys=rect.ymin; ys < rect.ymax; ys++) {
+ depth= v3d->depths->depths[ys*v3d->depths->w+xs];
+ if(depth < v3d->depths->depth_range[1] && depth > v3d->depths->depth_range[0]) {
+ if (depth_close > depth) {
+ depth_close = depth;
+ }
+ }
+ }
+ }
+
+ if (depth_close==MAXFLOAT)
+ return 0;
+
+ if (had_depth==0) {
+ MEM_freeN(v3d->depths->depths);
+ v3d->depths->depths = NULL;
+ }
+ v3d->depths->damaged = 1;
+
+ cent[0] = (double)mval[0];
+ cent[1] = (double)mval[1];
+
+ if (!gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
+ return 0;
+
+ mouse_worldloc[0] = (float)p[0];
+ mouse_worldloc[1] = (float)p[1];
+ mouse_worldloc[2] = (float)p[2];
+ return 1;
}
+
+/* ********************* NDOF ************************ */
+/* note: this code is confusing and unclear... (ton) */
+/* **************************************************** */
+
// ndof scaling will be moved to user setting.
// In the mean time this is just a place holder.
@@ -333,547 +884,6 @@ void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int mode)
// XXX BIF_view3d_previewrender_signal(ar, PR_DBASE|PR_DISPRECT);
}
-/* Zooms in on a border drawn by the user */
-static int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mouse_worldloc[3] ) //, float *autodist )
-{
- rcti rect;
- /* ZBuffer depth vars */
- bglMats mats;
- float depth, depth_close= MAXFLOAT;
- int had_depth = 0;
- double cent[2], p[3];
- int xs, ys;
-
-// XXX getmouseco_areawin(mval);
-
-// XXX persp(PERSP_VIEW);
-
- rect.xmax = mval[0] + 4;
- rect.ymax = mval[1] + 4;
-
- rect.xmin = mval[0] - 4;
- rect.ymin = mval[1] - 4;
-
- /* Get Z Depths, needed for perspective, nice for ortho */
- bgl_get_mats(&mats);
- draw_depth(scene, ar, v3d, NULL);
-
- /* force updating */
- if (v3d->depths) {
- had_depth = 1;
- v3d->depths->damaged = 1;
- }
-
- view3d_update_depths(ar, v3d);
-
- /* Constrain rect to depth bounds */
- if (rect.xmin < 0) rect.xmin = 0;
- if (rect.ymin < 0) rect.ymin = 0;
- if (rect.xmax >= v3d->depths->w) rect.xmax = v3d->depths->w-1;
- if (rect.ymax >= v3d->depths->h) rect.ymax = v3d->depths->h-1;
-
- /* Find the closest Z pixel */
- for (xs=rect.xmin; xs < rect.xmax; xs++) {
- for (ys=rect.ymin; ys < rect.ymax; ys++) {
- depth= v3d->depths->depths[ys*v3d->depths->w+xs];
- if(depth < v3d->depths->depth_range[1] && depth > v3d->depths->depth_range[0]) {
- if (depth_close > depth) {
- depth_close = depth;
- }
- }
- }
- }
-
- if (depth_close==MAXFLOAT)
- return 0;
-
- if (had_depth==0) {
- MEM_freeN(v3d->depths->depths);
- v3d->depths->depths = NULL;
- }
- v3d->depths->damaged = 1;
-
- cent[0] = (double)mval[0];
- cent[1] = (double)mval[1];
-
- if (!gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
- return 0;
-
- mouse_worldloc[0] = (float)p[0];
- mouse_worldloc[1] = (float)p[1];
- mouse_worldloc[2] = (float)p[2];
- return 1;
-}
-
-static void view_zoom_mouseloc(ARegion *ar, View3D *v3d, float dfac, short *mouseloc)
-{
- if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
- short vb[2];
- float dvec[3];
- float tvec[3];
- float tpos[3];
- float new_dist;
-
- /* find the current window width and height */
- vb[0] = ar->winx;
- vb[1] = ar->winy;
-
- tpos[0] = -v3d->ofs[0];
- tpos[1] = -v3d->ofs[1];
- tpos[2] = -v3d->ofs[2];
-
- /* Project cursor position into 3D space */
- initgrabz(v3d, tpos[0], tpos[1], tpos[2]);
- window_to_3d(ar, v3d, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
-
- /* Calculate view target position for dolly */
- tvec[0] = -(tpos[0] + dvec[0]);
- tvec[1] = -(tpos[1] + dvec[1]);
- tvec[2] = -(tpos[2] + dvec[2]);
-
- /* Offset to target position and dolly */
- new_dist = v3d->dist * dfac;
-
- VECCOPY(v3d->ofs, tvec);
- v3d->dist = new_dist;
-
- /* Calculate final offset */
- dvec[0] = tvec[0] + dvec[0] * dfac;
- dvec[1] = tvec[1] + dvec[1] * dfac;
- dvec[2] = tvec[2] + dvec[2] * dfac;
-
- VECCOPY(v3d->ofs, dvec);
- } else {
- v3d->dist *= dfac;
- }
-}
-
-
-#define COS45 0.70710678118654746
-#define SIN45 COS45
-
-void viewmove(Scene *scene, ARegion *ar, View3D *v3d, int mode)
-{
- static float lastofs[3] = {0,0,0};
- Object *ob = OBACT;
- float firstvec[3], newvec[3], dvec[3];
- float reverse, oldquat[4], q1[4], si, phi, dist0;
- float ofs[3], obofs[3]= {0.0f, 0.0f, 0.0f};
- int firsttime=1;
- short mvalball[2], mval[2], mvalo[2], mval_area[2], mvali[2];
- short use_sel = 0;
- short preview3d_event= 1;
-
- // locals for dist correction
- float mat[3][3];
- float upvec[3];
-
- /* 3D window may not be defined */
- if( !v3d ) {
- fprintf( stderr, "v3d == NULL in viewmove()\n" );
- return;
- }
-
- // dist correction from other movement devices
- if((dz_flag)||v3d->dist==0) {
- dz_flag = 0;
- v3d->dist = m_dist;
- upvec[0] = upvec[1] = 0;
- upvec[2] = v3d->dist;
- Mat3CpyMat4(mat, v3d->viewinv);
- Mat3MulVecfl(mat, upvec);
- VecAddf(v3d->ofs, v3d->ofs, upvec);
- }
-
- /* sometimes this routine is called from headerbuttons */
-
-// XXX areawinset(ar->win);
-
- QUATCOPY(oldquat, v3d->viewquat);
-
-// XXX getmouseco_areawin(mval_area); /* for zoom to mouse loc */
-// XXX getmouseco_sc(mvali); /* work with screen coordinates because of trackball function */
- mvalball[0]= mvalo[0] = mvali[0]; /* needed for turntable to work */
- mvalball[1]= mvalo[1] = mvali[1];
- dist0= v3d->dist;
-
- calctrackballvec(&ar->winrct, mvalo, firstvec);
-
- /* cumultime(0); */
-
- if(!G.obedit && (G.f & G_SCULPTMODE) && ob && v3d->pivot_last) {
- use_sel= 1;
- VecCopyf(ofs, v3d->ofs);
-
-// XXX VecCopyf(obofs, sculpt_data()->pivot);
- Mat4MulVecfl(ob->obmat, obofs);
- obofs[0]= -obofs[0];
- obofs[1]= -obofs[1];
- obofs[2]= -obofs[2];
- }
- else if (U.uiflag & USER_ORBIT_SELECTION) {
- use_sel = 1;
-
- VECCOPY(ofs, v3d->ofs);
-
- /* If there's no selection, lastofs is unmodified and last value since static */
-// XXX calculateTransformCenter(V3D_CENTROID, lastofs);
-
- VECCOPY(obofs, lastofs);
- VecMulf(obofs, -1.0f);
- }
- else if (U.uiflag & USER_ORBIT_ZBUF) {
- if ((use_sel= view_autodist(scene, ar, v3d, mval, obofs))) {
- if (v3d->persp==V3D_PERSP) {
- float my_origin[3]; /* original v3d->ofs */
- float my_pivot[3]; /* view */
-
- VECCOPY(my_origin, v3d->ofs);
- VecMulf(my_origin, -1.0f); /* ofs is flipped */
-
- /* Set the dist value to be the distance from this 3d point */
- /* this means youll always be able to zoom into it and panning wont go bad when dist was zero */
-
- /* remove dist value */
- upvec[0] = upvec[1] = 0;
- upvec[2] = v3d->dist;
- Mat3CpyMat4(mat, v3d->viewinv);
- Mat3MulVecfl(mat, upvec);
- VecSubf(my_pivot, v3d->ofs, upvec);
- VecMulf(my_pivot, -1.0f); /* ofs is flipped */
-
- /* find a new ofs value that is allong the view axis (rather then the mouse location) */
- lambda_cp_line_ex(obofs, my_pivot, my_origin, dvec);
- dist0 = v3d->dist = VecLenf(my_pivot, dvec);
-
- VecMulf(dvec, -1.0f);
- VECCOPY(v3d->ofs, dvec);
- }
- VecMulf(obofs, -1.0f);
- VECCOPY(ofs, v3d->ofs);
- } else {
- ofs[0] = ofs[1] = ofs[2] = 0.0f;
- }
- }
- else
- ofs[0] = ofs[1] = ofs[2] = 0.0f;
-
- initgrabz(v3d, -v3d->ofs[0], -v3d->ofs[1], -v3d->ofs[2]);
-
- reverse= 1.0f;
- if (v3d->persmat[2][1] < 0.0f)
- reverse= -1.0f;
-
- while(TRUE) {
-// XXX getmouseco_sc(mval);
-
- if( (mode==2 && U.viewzoom==USER_ZOOM_CONT) || /* continues zoom always update */
- mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { /* mouse moved, so update */
-
- if(firsttime) {
-
- firsttime= 0;
- /* are we translating, rotating or zooming? */
- if(mode==0) {
-// XXX if(v3d->view!=0) scrarea_queue_headredraw(ar); /*for button */
- }
- if(v3d->persp==V3D_CAMOB && mode!=1 && v3d->camera) {
- v3d->persp= V3D_PERSP;
-// XXX scrarea_do_windraw(ar);
-// XXX scrarea_queue_headredraw(ar);
- }
- }
-
- if(mode==0) { /* view rotate */
- v3d->view= 0; /* need to reset everytime because of view snapping */
-
- if (U.uiflag & USER_AUTOPERSP) v3d->persp= V3D_PERSP;
-
- if (U.flag & USER_TRACKBALL) mvalball[0]= mval[0];
- mvalball[1]= mval[1];
-
- calctrackballvec(&ar->winrct, mvalball, newvec);
-
- VecSubf(dvec, newvec, firstvec);
-
- si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]);
- si/= (2.0*TRACKBALLSIZE);
-
- if (U.flag & USER_TRACKBALL) {
- Crossf(q1+1, firstvec, newvec);
-
- Normalize(q1+1);
-
- /* Allow for rotation beyond the interval
- * [-pi, pi] */
- while (si > 1.0)
- si -= 2.0;
-
- /* This relation is used instead of
- * phi = asin(si) so that the angle
- * of rotation is linearly proportional
- * to the distance that the mouse is
- * dragged. */
- phi = si * M_PI / 2.0;
-
- si= sin(phi);
- q1[0]= cos(phi);
- q1[1]*= si;
- q1[2]*= si;
- q1[3]*= si;
- QuatMul(v3d->viewquat, q1, oldquat);
-
- if (use_sel) {
- /* compute the post multiplication quat, to rotate the offset correctly */
- QUATCOPY(q1, oldquat);
- QuatConj(q1);
- QuatMul(q1, q1, v3d->viewquat);
-
- QuatConj(q1); /* conj == inv for unit quat */
- VECCOPY(v3d->ofs, ofs);
- VecSubf(v3d->ofs, v3d->ofs, obofs);
- QuatMulVecf(q1, v3d->ofs);
- VecAddf(v3d->ofs, v3d->ofs, obofs);
- }
- } else {
- /* New turntable view code by John Aughey */
-
- float m[3][3];
- float m_inv[3][3];
- float xvec[3] = {1,0,0};
- /* Sensitivity will control how fast the viewport rotates. 0.0035 was
- obtained experimentally by looking at viewport rotation sensitivities
- on other modeling programs. */
- /* Perhaps this should be a configurable user parameter. */
- const float sensitivity = 0.0035;
-
- /* Get the 3x3 matrix and its inverse from the quaternion */
- QuatToMat3(v3d->viewquat, m);
- Mat3Inv(m_inv,m);
-
- /* Determine the direction of the x vector (for rotating up and down) */
- /* This can likely be compuated directly from the quaternion. */
- Mat3MulVecfl(m_inv,xvec);
-
- /* Perform the up/down rotation */
- phi = sensitivity * -(mval[1] - mvalo[1]);
- si = sin(phi);
- q1[0] = cos(phi);
- q1[1] = si * xvec[0];
- q1[2] = si * xvec[1];
- q1[3] = si * xvec[2];
- QuatMul(v3d->viewquat, v3d->viewquat, q1);
-
- if (use_sel) {
- QuatConj(q1); /* conj == inv for unit quat */
- VecSubf(v3d->ofs, v3d->ofs, obofs);
- QuatMulVecf(q1, v3d->ofs);
- VecAddf(v3d->ofs, v3d->ofs, obofs);
- }
-
- /* Perform the orbital rotation */
- phi = sensitivity * reverse * (mval[0] - mvalo[0]);
- q1[0] = cos(phi);
- q1[1] = q1[2] = 0.0;
- q1[3] = sin(phi);
- QuatMul(v3d->viewquat, v3d->viewquat, q1);
-
- if (use_sel) {
- QuatConj(q1);
- VecSubf(v3d->ofs, v3d->ofs, obofs);
- QuatMulVecf(q1, v3d->ofs);
- VecAddf(v3d->ofs, v3d->ofs, obofs);
- }
- }
-
- /* check for view snap */
- if (G.qual==LR_CTRLKEY){
- int i;
- float viewmat[3][3];
-
- static const float thres = 0.93f; //cos(20 deg);
-
- static float snapquats[39][6] = {
- /*{q0, q1, q3, q4, view, oposite_direction}*/
- {COS45, -SIN45, 0.0, 0.0, 1, 0}, //front
- {0.0, 0.0, -SIN45, -SIN45, 1, 1}, //back
- {1.0, 0.0, 0.0, 0.0, 7, 0}, //top
- {0.0, -1.0, 0.0, 0.0, 7, 1}, //bottom
- {0.5, -0.5, -0.5, -0.5, 3, 0}, //left
- {0.5, -0.5, 0.5, 0.5, 3, 1}, //right
-
- /* some more 45 deg snaps */
- {0.65328145027160645, -0.65328145027160645, 0.27059805393218994, 0.27059805393218994, 0, 0},
- {0.92387950420379639, 0.0, 0.0, 0.38268342614173889, 0, 0},
- {0.0, -0.92387950420379639, 0.38268342614173889, 0.0, 0, 0},
- {0.35355335474014282, -0.85355335474014282, 0.35355338454246521, 0.14644660055637360, 0, 0},
- {0.85355335474014282, -0.35355335474014282, 0.14644660055637360, 0.35355338454246521, 0, 0},
- {0.49999994039535522, -0.49999994039535522, 0.49999997019767761, 0.49999997019767761, 0, 0},
- {0.27059802412986755, -0.65328145027160645, 0.65328145027160645, 0.27059802412986755, 0, 0},
- {0.65328145027160645, -0.27059802412986755, 0.27059802412986755, 0.65328145027160645, 0, 0},
- {0.27059799432754517, -0.27059799432754517, 0.65328139066696167, 0.65328139066696167, 0, 0},
- {0.38268336653709412, 0.0, 0.0, 0.92387944459915161, 0, 0},
- {0.0, -0.38268336653709412, 0.92387944459915161, 0.0, 0, 0},
- {0.14644658565521240, -0.35355335474014282, 0.85355335474014282, 0.35355335474014282, 0, 0},
- {0.35355335474014282, -0.14644658565521240, 0.35355335474014282, 0.85355335474014282, 0, 0},
- {0.0, 0.0, 0.92387944459915161, 0.38268336653709412, 0, 0},
- {-0.0, 0.0, 0.38268336653709412, 0.92387944459915161, 0, 0},
- {-0.27059802412986755, 0.27059802412986755, 0.65328133106231689, 0.65328133106231689, 0, 0},
- {-0.38268339633941650, 0.0, 0.0, 0.92387938499450684, 0, 0},
- {0.0, 0.38268339633941650, 0.92387938499450684, 0.0, 0, 0},
- {-0.14644658565521240, 0.35355338454246521, 0.85355329513549805, 0.35355332493782043, 0, 0},
- {-0.35355338454246521, 0.14644658565521240, 0.35355332493782043, 0.85355329513549805, 0, 0},
- {-0.49999991059303284, 0.49999991059303284, 0.49999985098838806, 0.49999985098838806, 0, 0},
- {-0.27059799432754517, 0.65328145027160645, 0.65328139066696167, 0.27059799432754517, 0, 0},
- {-0.65328145027160645, 0.27059799432754517, 0.27059799432754517, 0.65328139066696167, 0, 0},
- {-0.65328133106231689, 0.65328133106231689, 0.27059793472290039, 0.27059793472290039, 0, 0},
- {-0.92387932538986206, 0.0, 0.0, 0.38268333673477173, 0, 0},
- {0.0, 0.92387932538986206, 0.38268333673477173, 0.0, 0, 0},
- {-0.35355329513549805, 0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0, 0},
- {-0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0.35355329513549805, 0, 0},
- {-0.38268330693244934, 0.92387938499450684, 0.0, 0.0, 0, 0},
- {-0.92387938499450684, 0.38268330693244934, 0.0, 0.0, 0, 0},
- {-COS45, 0.0, 0.0, SIN45, 0, 0},
- {COS45, 0.0, 0.0, SIN45, 0, 0},
- {0.0, 0.0, 0.0, 1.0, 0, 0}
- };
-
- QuatToMat3(v3d->viewquat, viewmat);
-
- for (i = 0 ; i < 39; i++){
- float snapmat[3][3];
- float view = (int)snapquats[i][4];
- float oposite_dir = (int)snapquats[i][5];
-
- QuatToMat3(snapquats[i], snapmat);
-
- if ((Inpf(snapmat[0], viewmat[0]) > thres) &&
- (Inpf(snapmat[1], viewmat[1]) > thres) &&
- (Inpf(snapmat[2], viewmat[2]) > thres)){
-
- QUATCOPY(v3d->viewquat, snapquats[i]);
-
- v3d->view = view;
- if (view){
- if (oposite_dir){
- v3d->flag2 |= V3D_OPP_DIRECTION_NAME;
- }else{
- v3d->flag2 &= ~V3D_OPP_DIRECTION_NAME;
- }
- }
-
- break;
- }
- }
- }
- }
- else if(mode==1) { /* translate */
- if(v3d->persp==V3D_CAMOB) {
- float max= (float)MAX2(ar->winx, ar->winy);
-
- v3d->camdx += (mvalo[0]-mval[0])/(max);
- v3d->camdy += (mvalo[1]-mval[1])/(max);
- CLAMP(v3d->camdx, -1.0f, 1.0f);
- CLAMP(v3d->camdy, -1.0f, 1.0f);
- preview3d_event= 0;
- }
- else {
- window_to_3d(ar, v3d, dvec, mval[0]-mvalo[0], mval[1]-mvalo[1]);
- VecAddf(v3d->ofs, v3d->ofs, dvec);
- }
- }
- else if(mode==2) {
- float zfac=1.0;
-
- /* use initial value (do not use mvalo (that is used to detect mouse moviments)) */
- mvalo[0] = mvali[0];
- mvalo[1] = mvali[1];
-
- if(U.viewzoom==USER_ZOOM_CONT) {
- // oldstyle zoom
- zfac = 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0;
- }
- else if(U.viewzoom==USER_ZOOM_SCALE) {
- int ctr[2], len1, len2;
- // method which zooms based on how far you move the mouse
-
- ctr[0] = (ar->winrct.xmax + ar->winrct.xmin)/2;
- ctr[1] = (ar->winrct.ymax + ar->winrct.ymin)/2;
-
- len1 = (int)sqrt((ctr[0] - mval[0])*(ctr[0] - mval[0]) + (ctr[1] - mval[1])*(ctr[1] - mval[1])) + 5;
- len2 = (int)sqrt((ctr[0] - mvalo[0])*(ctr[0] - mvalo[0]) + (ctr[1] - mvalo[1])*(ctr[1] - mvalo[1])) + 5;
-
- zfac = dist0 * ((float)len2/len1) / v3d->dist;
- }
- else { /* USER_ZOOM_DOLLY */
- float len1 = (ar->winrct.ymax - mval[1]) + 5;
- float len2 = (ar->winrct.ymax - mvalo[1]) + 5;
- zfac = dist0 * (2.0*((len2/len1)-1.0) + 1.0) / v3d->dist;
- }
-
- if(zfac != 1.0 && zfac*v3d->dist > 0.001*v3d->grid &&
- zfac*v3d->dist < 10.0*v3d->far)
- view_zoom_mouseloc(ar, v3d, zfac, mval_area);
-
-
- if ((U.uiflag & USER_ORBIT_ZBUF) && (U.viewzoom==USER_ZOOM_CONT) && (v3d->persp==V3D_PERSP)) {
- /* Secret apricot feature, translate the view when in continues mode */
- upvec[0] = upvec[1] = 0;
- upvec[2] = (dist0 - v3d->dist) * v3d->grid;
- v3d->dist = dist0;
- Mat3CpyMat4(mat, v3d->viewinv);
- Mat3MulVecfl(mat, upvec);
- VecAddf(v3d->ofs, v3d->ofs, upvec);
- } else {
- /* these limits are in toets.c too */
- if(v3d->dist<0.001*v3d->grid) v3d->dist= 0.001*v3d->grid;
- if(v3d->dist>10.0*v3d->far) v3d->dist=10.0*v3d->far;
- }
-
- if(v3d->persp==V3D_ORTHO || v3d->persp==V3D_CAMOB) preview3d_event= 0;
- }
-
-
-
- mvalo[0]= mval[0];
- mvalo[1]= mval[1];
-
-// XXX if(G.f & G_PLAYANIM) inner_play_anim_loop(0, 0);
-
- /* If in retopo paint mode, update lines */
- if(retopo_mesh_paint_check() && v3d->retopo_view_data) {
- v3d->retopo_view_data->queue_matrix_update= 1;
- retopo_paint_view_update(v3d);
- }
-
-// XXX scrarea_do_windraw(ar);
-// XXX screen_swapbuffers();
- }
- else {
-// short val;
-// unsigned short event;
- /* we need to empty the queue... when you do this very long it overflows */
-// XX while(qtest()) event= extern_qread(&val);
-
-// XXX BIF_wait_for_statechange();
- }
-
- /* this in the end, otherwise get_mbut does not work on a PC... */
-// XXX if( !(get_mbut() & (L_MOUSE|M_MOUSE))) break;
- }
-
- if(v3d->depths) v3d->depths->damaged= 1;
-// XXX retopo_queue_updates(v3d);
-// XXX allqueue(REDRAWVIEW3D, 0);
-
-// XXX if(preview3d_event)
-// BIF_view3d_previewrender_signal(ar, PR_DBASE|PR_DISPRECT);
-// else
-// BIF_view3d_previewrender_signal(ar, PR_PROJECTED);
-
-}
-
-
void viewmoveNDOF(Scene *scene, View3D *v3d, int mode)
{
float fval[7];
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 6c0a978f088..4067fb2bc4c 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -33,6 +33,7 @@
struct BoundBox;
struct Object;
struct DerivedMesh;
+struct wmOperatorType;
typedef struct ViewDepths {
unsigned short w, h;
@@ -56,6 +57,15 @@ typedef struct ViewDepths {
/* view3d_header.c */
void view3d_header_buttons(const struct bContext *C, ARegion *ar);
+/* view3d_ops.c */
+void view3d_operatortypes(void);
+void view3d_keymap(struct wmWindowManager *wm);
+
+/* view3d_edit.c */
+void ED_VIEW3D_OT_viewzoom(struct wmOperatorType *ot);
+void ED_VIEW3D_OT_viewmove(struct wmOperatorType *ot);
+void ED_VIEW3D_OT_viewrotate(struct wmOperatorType *ot);
+
/* drawobject.c */
void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag);
int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
new file mode 100644
index 00000000000..31b7fe33ea7
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -0,0 +1,77 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+
+#include "view3d_intern.h"
+
+
+/* ************************** registration **********************************/
+
+void view3d_operatortypes(void)
+{
+ WM_operatortype_append(ED_VIEW3D_OT_viewrotate);
+ WM_operatortype_append(ED_VIEW3D_OT_viewmove);
+ WM_operatortype_append(ED_VIEW3D_OT_viewzoom);
+}
+
+void view3d_keymap(wmWindowManager *wm)
+{
+ ListBase *keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0);
+
+ WM_keymap_verify_item(keymap, "ED_VIEW3D_OT_viewrotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "ED_VIEW3D_OT_viewmove", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_verify_item(keymap, "ED_VIEW3D_OT_viewzoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
+}
+