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:
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r--source/blender/editors/space_view3d/Makefile5
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c121
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c101
-rw-r--r--source/blender/editors/space_view3d/drawobject.c1288
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c1
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c189
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c139
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c305
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c72
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h20
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c108
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c13
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c874
15 files changed, 2432 insertions, 817 deletions
diff --git a/source/blender/editors/space_view3d/Makefile b/source/blender/editors/space_view3d/Makefile
index 07102157854..9204f2482c6 100644
--- a/source/blender/editors/space_view3d/Makefile
+++ b/source/blender/editors/space_view3d/Makefile
@@ -53,6 +53,9 @@ CPPFLAGS += -I../../render/extern/include
CPPFLAGS += -I../../blenfont
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
CPPFLAGS += -I$(NAN_SMOKE)/include
-# own include
+ifneq ($(NAN_NO_KETSJI),true)
+ CPPFLAGS += -I../../../kernel/gen_system
+endif
+# own include
CPPFLAGS += -I../include
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index fa810677fe8..26135cd8d31 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -639,7 +639,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
/* figure out the sizes of spheres */
if (ebone) {
- /* this routine doesn't call set_matrix_editbone() that calculates it */
+ /* this routine doesn't call get_matrix_editbone() that calculates it */
ebone->length = VecLenf(ebone->head, ebone->tail);
length= ebone->length;
@@ -749,7 +749,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
/* figure out the sizes of spheres */
if (ebone) {
- /* this routine doesn't call set_matrix_editbone() that calculates it */
+ /* this routine doesn't call get_matrix_editbone() that calculates it */
ebone->length = VecLenf(ebone->head, ebone->tail);
length= ebone->length;
@@ -1516,15 +1516,25 @@ static void draw_pose_dofs(Object *ob)
}
}
+static void bone_matrix_translate_y(float mat[][4], float y)
+{
+ float trans[3];
+
+ VECCOPY(trans, mat[1]);
+ VecMulf(trans, y);
+ VecAddf(mat[3], mat[3], trans);
+}
+
/* assumes object is Armature with pose */
-static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt)
+static void draw_pose_channels(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt)
{
+ RegionView3D *rv3d= ar->regiondata;
Object *ob= base->object;
bArmature *arm= ob->data;
bPoseChannel *pchan;
Bone *bone;
GLfloat tmp;
- float smat[4][4], imat[4][4];
+ float smat[4][4], imat[4][4], bmat[4][4];
int index= -1;
short do_dashed= 3, draw_wire= 0;
short flag, constflag;
@@ -1644,6 +1654,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba
/* prepare colors */
if (arm->flag & ARM_POSEMODE)
set_pchan_colorset(ob, pchan);
+#if 0 // XXX - 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith)
else {
if ((scene->basact)==base) {
if (base->flag & (SELECT+BA_WAS_SEL)) UI_ThemeColor(TH_ACTIVE);
@@ -1654,6 +1665,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba
else UI_ThemeColor(TH_WIRE);
}
}
+#endif
/* catch exception for bone with hidden parent */
flag= bone->flag;
@@ -1745,7 +1757,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba
/* extra draw service for pose mode */
constflag= pchan->constflag;
- if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) // XXX this is useless crap
+ if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE))
constflag |= PCHAN_HAS_ACTION;
if (pchan->flag & POSE_STRIDE)
constflag |= PCHAN_HAS_STRIDE;
@@ -1809,15 +1821,21 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba
/* Draw names of bone */
if (arm->flag & ARM_DRAWNAMES) {
VecMidf(vec, pchan->pose_head, pchan->pose_tail);
- view3d_object_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10);
+ view3d_cached_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10);
}
/* Draw additional axes on the bone tail */
if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) {
glPushMatrix();
- glMultMatrixf(pchan->pose_mat);
- glTranslatef(0.0f, pchan->bone->length, 0.0f);
- drawaxes(0.25f*pchan->bone->length, 0, OB_ARROWS);
+ Mat4CpyMat4(bmat, pchan->pose_mat);
+ bone_matrix_translate_y(bmat, pchan->bone->length);
+ glMultMatrixf(bmat);
+
+ /* do cached text draw immediate to include transform */
+ view3d_cached_text_draw_begin();
+ drawaxes(pchan->bone->length*0.25f, 0, OB_ARROWS);
+ view3d_cached_text_draw_end(v3d, ar, 1, bmat);
+
glPopMatrix();
}
}
@@ -1830,32 +1848,28 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba
}
/* in editmode, we don't store the bone matrix... */
-static void set_matrix_editbone(EditBone *eBone)
+static void get_matrix_editbone(EditBone *eBone, float bmat[][4])
{
- float delta[3],offset[3];
- float mat[3][3], bmat[4][4];
+ float delta[3];
+ float mat[3][3];
/* Compose the parent transforms (i.e. their translations) */
- VECCOPY(offset, eBone->head);
-
- glTranslatef(offset[0],offset[1],offset[2]);
-
VecSubf(delta, eBone->tail, eBone->head);
eBone->length = (float)sqrt(delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]);
vec_roll_to_mat3(delta, eBone->roll, mat);
Mat4CpyMat3(bmat, mat);
-
- glMultMatrixf(bmat);
-
+
+ VecAddf(bmat[3], bmat[3], eBone->head);
}
-static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
+static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt)
{
+ RegionView3D *rv3d= ar->regiondata;
EditBone *eBone;
bArmature *arm= ob->data;
- float smat[4][4], imat[4][4];
+ float smat[4][4], imat[4][4], bmat[4][4];
unsigned int index;
int flag;
@@ -1893,7 +1907,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A)==0) {
glPushMatrix();
- set_matrix_editbone(eBone);
+ get_matrix_editbone(eBone, bmat);
+ glMultMatrixf(bmat);
/* catch exception for bone with hidden parent */
flag= eBone->flag;
@@ -1941,7 +1956,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
}
else {
glPushMatrix();
- set_matrix_editbone(eBone);
+ get_matrix_editbone(eBone, bmat);
+ glMultMatrixf(bmat);
if (arm->drawtype == ARM_LINE)
draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
@@ -1994,14 +2010,20 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
if (arm->flag & ARM_DRAWNAMES) {
VecMidf(vec, eBone->head, eBone->tail);
glRasterPos3fv(vec);
- view3d_object_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10);
+ view3d_cached_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10);
}
/* Draw additional axes */
if (arm->flag & ARM_DRAWAXES) {
glPushMatrix();
- set_matrix_editbone(eBone);
- glTranslatef(0.0f, eBone->length, 0.0f);
+ get_matrix_editbone(eBone, bmat);
+ bone_matrix_translate_y(bmat, eBone->length);
+ glMultMatrixf(bmat);
+
+ /* do cached text draw immediate to include transform */
+ view3d_cached_text_draw_begin();
drawaxes(eBone->length*0.25f, 0, OB_ARROWS);
+ view3d_cached_text_draw_end(v3d, ar, 1, bmat);
+
glPopMatrix();
}
@@ -2021,8 +2043,9 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
/* draw bone paths
* - in view space
*/
-static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
+static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob)
{
+ RegionView3D *rv3d= ar->regiondata;
AnimData *adt= BKE_animdata_from_id(&ob->id);
bArmature *arm= ob->data;
bPoseChannel *pchan;
@@ -2155,12 +2178,12 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
/* only draw framenum if several consecutive highlighted points don't occur on same point */
if (a == 0) {
sprintf(str, "%d", (a+sfra));
- view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0);
+ view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
}
else if ((a > stepsize) && (a < len-stepsize)) {
if ((VecEqual(fp, fp-(stepsize*3))==0) || (VecEqual(fp, fp+(stepsize*3))==0)) {
sprintf(str, "%d", (a+sfra));
- view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0);
+ view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
}
}
}
@@ -2202,7 +2225,7 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
char str[32];
sprintf(str, "%d", (a+sfra));
- view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0);
+ view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
}
}
}
@@ -2253,7 +2276,7 @@ static void ghost_poses_tag_unselected(Object *ob, short unset)
/* draw ghosts that occur within a frame range
* note: object should be in posemode
*/
-static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
{
Object *ob= base->object;
AnimData *adt= BKE_animdata_from_id(&ob->id);
@@ -2295,7 +2318,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d
BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
- draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+ draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2315,7 +2338,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d
/* draw ghosts on keyframes in action within range
* - object should be in posemode
*/
-static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
{
Object *ob= base->object;
AnimData *adt= BKE_animdata_from_id(&ob->id);
@@ -2374,7 +2397,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d,
BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
- draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+ draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2394,7 +2417,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d,
/* draw ghosts around current frame
* - object is supposed to be armature in posemode
*/
-static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
{
Object *ob= base->object;
AnimData *adt= BKE_animdata_from_id(&ob->id);
@@ -2444,7 +2467,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
- draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+ draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
}
}
@@ -2459,7 +2482,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
where_is_pose(scene, ob);
- draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+ draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
}
}
}
@@ -2480,7 +2503,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
/* ********************************** Armature Drawing - Main ************************* */
/* called from drawobject.c, return 1 if nothing was drawn */
-int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag)
+int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag)
{
Object *ob= base->object;
bArmature *arm= ob->data;
@@ -2504,7 +2527,7 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int
/* editmode? */
if(arm->edbo) {
arm->flag |= ARM_EDITMODE;
- draw_ebones(v3d, rv3d, ob, dt);
+ draw_ebones(v3d, ar, ob, dt);
arm->flag &= ~ARM_EDITMODE;
}
else{
@@ -2513,32 +2536,36 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int
/* drawing posemode selection indices or colors only in these cases */
if(!(base->flag & OB_FROMDUPLI)) {
if(G.f & G_PICKSEL) {
- if(ob->mode & OB_MODE_POSE)
+ if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) {
+ if(ob==modifiers_isDeformedByArmature(OBACT))
+ arm->flag |= ARM_POSEMODE;
+ }
+ else if(ob->mode & OB_MODE_POSE)
arm->flag |= ARM_POSEMODE;
}
else if(ob->mode & OB_MODE_POSE) {
if (arm->ghosttype == ARM_GHOST_RANGE) {
- draw_ghost_poses_range(scene, v3d, rv3d, base);
+ draw_ghost_poses_range(scene, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_KEYS) {
- draw_ghost_poses_keys(scene, v3d, rv3d, base);
+ draw_ghost_poses_keys(scene, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_CUR) {
if (arm->ghostep)
- draw_ghost_poses(scene, v3d, rv3d, base);
+ draw_ghost_poses(scene, v3d, ar, base);
}
if ((flag & DRAW_SCENESET)==0) {
if(ob==OBACT)
arm->flag |= ARM_POSEMODE;
- else if(ob->mode & OB_MODE_WEIGHT_PAINT) {
- if(OBACT && ob==modifiers_isDeformedByArmature(OBACT))
+ else if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) {
+ if(ob==modifiers_isDeformedByArmature(OBACT))
arm->flag |= ARM_POSEMODE;
}
- draw_pose_paths(scene, v3d, rv3d, ob);
+ draw_pose_paths(scene, v3d, ar, ob);
}
}
}
- draw_pose_channels(scene, v3d, rv3d, base, dt);
+ draw_pose_channels(scene, v3d, ar, base, dt);
arm->flag &= ~ARM_POSEMODE;
if(ob->mode & OB_MODE_POSE)
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 2e47e2d4483..0d8e1381756 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -71,6 +71,7 @@
#include "UI_resources.h"
#include "UI_interface_icons.h"
+#include "gpu_buffers.h"
#include "GPU_extensions.h"
#include "GPU_draw.h"
@@ -350,7 +351,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
int istex, solidtex= 0;
// XXX scene->obedit warning
- if(v3d->drawtype==OB_SOLID || (ob==scene->obedit && v3d->drawtype!=OB_TEXTURE)) {
+ if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
/* draw with default lights in solid draw mode and edit mode */
solidtex= 1;
Gtexdraw.islit= -1;
@@ -399,8 +400,7 @@ static void draw_textured_end()
glPopMatrix();
}
-
-static int draw_tface__set_draw(MTFace *tface, int has_vcol, int matnr)
+static int draw_tface__set_draw_legacy(MTFace *tface, int has_vcol, int matnr)
{
if (tface && (tface->mode&TF_INVISIBLE)) return 0;
@@ -422,6 +422,87 @@ static int draw_tface__set_draw(MTFace *tface, int has_vcol, int matnr)
return 1; /* Set color from mcol */
}
}
+static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
+{
+ if (tface && (tface->mode&TF_INVISIBLE)) return 0;
+
+ if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
+ return 2; /* Don't set color */
+ } else if (tface && tface->mode&TF_OBCOL) {
+ return 2; /* Don't set color */
+ } else if (!mcol) {
+ return 2; /* Don't set color */
+ } else {
+ return 1; /* Set color from mcol */
+ }
+}
+static void add_tface_color_layer(DerivedMesh *dm)
+{
+ MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
+ MFace *mface = dm->getTessFaceArray(dm);
+ MCol *finalCol;
+ int i,j;
+ MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
+ if(!mcol)
+ mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
+
+ finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumTessFaces(dm),"add_tface_color_layer");
+ for(i=0;i<dm->getNumTessFaces(dm);i++) {
+ if (tface && (tface->mode&TF_INVISIBLE)) {
+ if( mcol )
+ memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
+ else
+ for(j=0;j<4;j++) {
+ finalCol[i*4+j].b = 255;
+ finalCol[i*4+j].g = 255;
+ finalCol[i*4+j].r = 255;
+ }
+ }
+ else if (tface && mface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, mface[i].mat_nr, TF_TWOSIDE)) {
+ for(j=0;j<4;j++) {
+ finalCol[i*4+j].b = 255;
+ finalCol[i*4+j].g = 0;
+ finalCol[i*4+j].r = 255;
+ }
+ } else if (tface && tface->mode&TF_OBCOL) {
+ for(j=0;j<4;j++) {
+ finalCol[i*4+j].r = Gtexdraw.obcol[0];
+ finalCol[i*4+j].g = Gtexdraw.obcol[1];
+ finalCol[i*4+j].b = Gtexdraw.obcol[2];
+ }
+ } else if (!mcol) {
+ if (tface) {
+ for(j=0;j<4;j++) {
+ finalCol[i*4+j].b = 255;
+ finalCol[i*4+j].g = 255;
+ finalCol[i*4+j].r = 255;
+ }
+ }
+ else {
+ Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
+ if(ma)
+ for(j=0;j<4;j++) {
+ finalCol[i*4+j].b = ma->b;
+ finalCol[i*4+j].g = ma->g;
+ finalCol[i*4+j].r = ma->r;
+ }
+ else
+ for(j=0;j<4;j++) {
+ finalCol[i*4+j].b = 255;
+ finalCol[i*4+j].g = 255;
+ finalCol[i*4+j].r = 255;
+ }
+ }
+ } else {
+ for(j=0;j<4;j++) {
+ finalCol[i*4+j].b = mcol[i*4+j].r;
+ finalCol[i*4+j].g = mcol[i*4+j].g;
+ finalCol[i*4+j].r = mcol[i*4+j].b;
+ }
+ }
+ }
+ CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
+}
static int draw_tface_mapped__set_draw(void *userData, int index)
{
@@ -504,7 +585,7 @@ void draw_mesh_text(Scene *scene, Object *ob, int glsl)
return;
/* don't draw when editing */
- if(ob == scene->obedit)
+ if(ob->mode & OB_MODE_EDIT)
return;
else if(ob==OBACT)
if(paint_facesel_test(ob))
@@ -584,7 +665,8 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
/* draw the textured mesh */
draw_textured_begin(scene, v3d, rv3d, ob);
- if(ob == scene->obedit) {
+ if(ob->mode & OB_MODE_EDIT) {
+ glColor4f(1.0f,1.0f,1.0f,1.0f);
dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_btmesh);
} else if(faceselect) {
if(ob->mode & OB_MODE_WEIGHT_PAINT)
@@ -593,7 +675,14 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, me);
}
else {
- dm->drawFacesTex(dm, draw_tface__set_draw);
+ if( GPU_buffer_legacy(dm) )
+ dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
+ else {
+ glColor4f(1.0f,1.0f,1.0f,1.0f);
+ if( !CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL) )
+ add_tface_color_layer(dm);
+ dm->drawFacesTex(dm, draw_tface__set_draw);
+ }
}
/* draw game engine text hack */
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 482b4718504..dfbdce14992 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -104,6 +104,7 @@
#include "GPU_draw.h"
#include "GPU_material.h"
#include "GPU_extensions.h"
+#include "gpu_buffers.h"
#include "ED_mesh.h"
#include "ED_particle.h"
@@ -115,6 +116,7 @@
#include "UI_interface_icons.h"
#include "WM_api.h"
+#include "wm_subwindow.h"
#include "BLF_api.h"
#include "view3d_intern.h" // own include
@@ -139,7 +141,9 @@ static void draw_empty_sphere(float size);
static void draw_empty_cone(float size);
-/* ************* only use while object drawing ************** */
+/* ************* only use while object drawing **************
+ * or after running ED_view3d_init_mats_rv3d
+ * */
static void view3d_project_short_clip(ARegion *ar, float *vec, short *adr)
{
RegionView3D *rv3d= ar->regiondata;
@@ -436,11 +440,11 @@ void drawaxes(float size, int flag, char drawtype)
// patch for 3d cards crashing on glSelect for text drawing (IBM)
if((flag & DRAW_PICKING) == 0) {
if (axis==0)
- view3d_object_text_draw_add(v2[0], v2[1], v2[2], "x", 0);
+ view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "x", 0);
else if (axis==1)
- view3d_object_text_draw_add(v2[0], v2[1], v2[2], "y", 0);
+ view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "y", 0);
else
- view3d_object_text_draw_add(v2[0], v2[1], v2[2], "z", 0);
+ view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "z", 0);
}
}
break;
@@ -498,23 +502,32 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, float *vec, int se
if(v3d->zbuf) glDepthFunc(GL_LEQUAL);
}
-/* *********** text drawing for object ************* */
-static ListBase strings= {NULL, NULL};
+/* *********** text drawing for object/particles/armature ************* */
-typedef struct ViewObjectString {
- struct ViewObjectString *next, *prev;
+static ListBase CachedText[3];
+static int CachedTextLevel= 0;
+
+typedef struct ViewCachedString {
+ struct ViewCachedString *next, *prev;
float vec[3], col[4];
char str[128];
short mval[2];
short xoffs;
-} ViewObjectString;
+} ViewCachedString;
+void view3d_cached_text_draw_begin()
+{
+ ListBase *strings= &CachedText[CachedTextLevel];
+ strings->first= strings->last= NULL;
+ CachedTextLevel++;
+}
-void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs)
+void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs)
{
- ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString");
+ ListBase *strings= &CachedText[CachedTextLevel-1];
+ ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString), "ViewCachedString");
- BLI_addtail(&strings, vos);
+ BLI_addtail(strings, vos);
BLI_strncpy(vos->str, str, 128);
vos->vec[0]= x;
vos->vec[1]= y;
@@ -523,22 +536,23 @@ void view3d_object_text_draw_add(float x, float y, float z, char *str, short xof
vos->xoffs= xoffs;
}
-static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4])
{
- ViewObjectString *vos;
- int tot= 0;
+ RegionView3D *rv3d= ar->regiondata;
+ ListBase *strings= &CachedText[CachedTextLevel-1];
+ ViewCachedString *vos;
+ int a, tot= 0;
/* project first and test */
- for(vos= strings.first; vos; vos= vos->next) {
+ for(vos= strings->first; vos; vos= vos->next) {
+ if(mat)
+ Mat4MulVecfl(mat, vos->vec);
view3d_project_short_clip(ar, vos->vec, vos->mval);
if(vos->mval[0]!=IS_CLIPPED)
tot++;
}
-
+
if(tot) {
- RegionView3D *rv3d= ar->regiondata;
- int a;
-
if(rv3d->rflag & RV3D_CLIPPING)
for(a=0; a<6; a++)
glDisable(GL_CLIP_PLANE0+a);
@@ -546,16 +560,22 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
wmPushMatrix();
ED_region_pixelspace(ar);
- if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ if(depth_write) {
+ if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ }
+ else glDepthMask(0);
- for(vos= strings.first; vos; vos= vos->next) {
+ for(vos= strings->first; vos; vos= vos->next) {
if(vos->mval[0]!=IS_CLIPPED) {
glColor3fv(vos->col);
- BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 0.0, vos->str);
+ BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, vos->str);
}
}
- if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ if(depth_write) {
+ if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ }
+ else glDepthMask(1);
wmPopMatrix();
@@ -564,10 +584,14 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
glEnable(GL_CLIP_PLANE0+a);
}
- if(strings.first)
- BLI_freelistN(&strings);
+ if(strings->first)
+ BLI_freelistN(strings);
+
+ CachedTextLevel--;
}
+/* ******************** primitive drawing ******************* */
+
static void drawcube(void)
{
@@ -1279,6 +1303,10 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob)
/* ***************** ******************** */
+/* Note! - foreach funcs should be called while drawing or directly after
+ * if not, ED_view3d_init_mats_rv3d() can be used for selection tools
+ * but would not give correct results with dupli's for eg. which dont
+ * use the object matrix in the useual way */
static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
struct { void (*func)(void *userData, BMVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
@@ -1613,9 +1641,28 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *
}
}
}
+
+/* disabled because it crashes combined with e.g. subsurf modifier,
+ * the derivedmesh can't be assumed to be an EditMeshDerivedMesh,
+ * nor should this struct be copied around, it should be defined in
+ * a single place only to avoid them getting out of sync */
+#if 0
+/* originally defined in DerivedMesh.c */
+typedef struct {
+ DerivedMesh dm;
+
+ EditMesh *em;
+ float (*vertexCos)[3];
+ float (*vertexNos)[3];
+ float (*faceNos)[3];
+} EditMeshDerivedMesh;
+#endif
+
static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act)
{
struct { BMEditMesh *em; int sel; BMVert *eve_act; } data;
+ //GPUBuffer *buffer;
+ //float *varray;
data.sel = sel;
data.eve_act = eve_act;
data.em = em;
@@ -1623,6 +1670,59 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_
bglBegin(GL_POINTS);
dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
bglEnd();
+
+#if 0
+ /* first come the unselected vertices, then the selected */
+ buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( sizeof(float)*3*dm->getNumVerts(dm)*2, 0 );
+
+ if( (varray = GPU_buffer_lock_stream( buffer )) && bglPointHack() == 0 ) {
+ EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
+ EditVert *eve;
+ int i;
+ int numverts = 0, numselected = 0;
+ int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END };
+ GPU_buffer_unlock( buffer );
+ GPU_interleaved_setup( buffer, datatype );
+ varray = GPU_buffer_lock_stream( buffer );
+
+ glBegin(GL_POINTS);
+ for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
+ if (eve->h==0 && (eve->f&SELECT)==data.sel) {
+ if (eve==data.eve_act) {
+ if (emdm->vertexCos) {
+ VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],emdm->vertexCos[i]);
+ }
+ else {
+ VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],eve->co);
+ }
+ numselected++;
+ } else {
+ if (emdm->vertexCos) {
+ VECCOPY(&varray[3*numverts],emdm->vertexCos[i]);
+ } else {
+ VECCOPY(&varray[3*numverts],eve->co);
+ }
+ numverts++;
+ }
+ }
+ }
+ glEnd();
+ GPU_buffer_unlock( buffer );
+ glDrawArrays(GL_POINTS,0,numverts);
+ UI_ThemeColor4(TH_EDITMESH_ACTIVE);
+ glDrawArrays(GL_POINTS,dm->getNumVerts(dm),numselected);
+ UI_ThemeColor4(data.sel?TH_VERTEX_SELECT:TH_VERTEX);
+ GPU_buffer_unbind();
+ }
+ {
+#endif
+ bglBegin(GL_POINTS);
+ dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
+ bglEnd();
+#if 0
+ }
+ GPU_buffer_free( buffer, 0 );
+#endif
}
/* Draw edges with color set based on selection */
@@ -1680,30 +1780,73 @@ static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm)
/* Draw edges with color interpolated based on selection */
static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index)
{
- return !BM_TestHFlag(EDBM_get_edge_for_index(((void**)userData)[1], index), BM_HIDDEN);
+ return !BM_TestHFlag(EDBM_get_edge_for_index(((void**)userData)[0], index), BM_HIDDEN);
}
static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t)
{
- BMEdge *eed = EDBM_get_edge_for_index(((void**)userData)[1], index);
- unsigned char **cols = ((void**)userData)[0];
- unsigned char *col0 = cols[(BM_TestHFlag(eed->v1, BM_SELECT))?1:0];
- unsigned char *col1 = cols[(BM_TestHFlag(eed->v2, BM_SELECT))?1:0];
+ BMEdge *eed = EDBM_get_edge_for_index(((void**)userData)[0], index);
+ unsigned char **cols = userData;
+ unsigned char *col0 = cols[(BM_TestHFlag(eed->v1, BM_SELECT))?2:1];
+ unsigned char *col1 = cols[(BM_TestHFlag(eed->v2, BM_SELECT))?2:1];
glColor4ub( col0[0] + (col1[0]-col0[0])*t,
col0[1] + (col1[1]-col0[1])*t,
col0[2] + (col1[2]-col0[2])*t,
col0[3] + (col1[3]-col0[3])*t);
}
-static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm,
- unsigned char *baseCol, unsigned char *selCol)
-{
- unsigned char *cols[2];
- void *ptrs[2] = {cols, em};
- cols[0] = baseCol;
- cols[1] = selCol;
- dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions,
- draw_dm_edges_sel_interp__setDrawInterpOptions, ptrs);
+static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
+{
+ unsigned char *cols[3] = {em, baseCol, selCol};
+#if 0
+ int elemsize = sizeof(float)*3+sizeof(unsigned char)*4;
+ EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm;
+ EditMesh *em= emdm->em;
+ unsigned char *varray;
+ int i;
+ GPUBuffer *buffer;
+
+ buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( elemsize*em->totedge*2, 0 );
+ if( (varray = GPU_buffer_lock_stream( buffer )) ) {
+ EditEdge *eed;
+ int numedges = 0;
+ int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END };
+ GPU_buffer_unlock( buffer );
+ GPU_interleaved_setup( buffer, datatype );
+ varray = GPU_buffer_lock_stream( buffer );
+ for (i=0,eed= em->edges.first; eed; i++,eed= eed->next) {
+ if(eed->h==0) {
+ unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0];
+ unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0];
+
+ if( emdm->vertexCos ) {
+ VECCOPY(((float *)&varray[elemsize*numedges*2]),emdm->vertexCos[(int) eed->v1->tmp.l]);
+ }
+ else {
+ VECCOPY(((float *)&varray[elemsize*numedges*2]),eed->v1->co);
+ }
+ QUATCOPY(&varray[elemsize*numedges*2+sizeof(float)*3],col0);
+ if( emdm->vertexCos ) {
+ VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),emdm->vertexCos[(int) eed->v2->tmp.l]);
+ }
+ else {
+ VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),eed->v2->co);
+ }
+ QUATCOPY(&varray[elemsize*numedges*2+elemsize+sizeof(float)*3],col1);
+ numedges++;
+ }
+ }
+ GPU_buffer_unlock( buffer );
+ glDrawArrays(GL_LINES,0,numedges*2);
+ GPU_buffer_unbind();
+ }
+ else {
+#endif
+ dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
+#if 0
+ }
+ GPU_buffer_free( buffer, 0 );
+#endif
}
/* Draw only seam edges */
@@ -1826,14 +1969,242 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba
{
struct { unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} data;
+ //EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm;
+ BMFace *efa;
+ unsigned char *col;
+ GPUBuffer *buffer;
+ unsigned char *varray;
+ unsigned char black[] = { 0, 0, 0, 0 };
+ int i, draw=0;
+ int elemsize = (sizeof(float)*6+sizeof(unsigned char)*4);
data.cols[0] = baseCol;
data.em = em;
data.cols[1] = selCol;
data.cols[2] = actCol;
data.efa_act = efa_act;
data.me = me;
-
- dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0);
+
+#if 0 //BMESH_TODO
+ buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( elemsize*dm->getNumFaces(dm)*3*2, 0 );
+ if( dm->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
+ int prevdraw = 0;
+ int numfaces = 0;
+ int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END };
+ GPU_buffer_unlock( buffer );
+ GPU_interleaved_setup( buffer, datatype );
+ glShadeModel(GL_SMOOTH);
+ varray = GPU_buffer_lock_stream( buffer );
+ for (i=0,efa= efa_act; efa; i++,efa= efa->next) {
+ int drawSmooth = (efa->flag & ME_SMOOTH);
+ if (efa->h==0) {
+ if (efa == data.efa_act) {
+ draw = 2;
+ } else {
+ col = data.cols[(efa->f&SELECT)?1:0];
+ if (col[3]==0) draw = 0;
+ else draw = 1;
+ }
+ }
+ else {
+ draw = 0;
+ }
+ if( prevdraw != draw && prevdraw != 0 && numfaces > 0) {
+ if( prevdraw==2 ) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
+ }
+ GPU_buffer_unlock( buffer );
+ glDrawArrays(GL_TRIANGLES,0,numfaces*3);
+ if( prevdraw==2 ) {
+ glDisable(GL_POLYGON_STIPPLE);
+ }
+ varray = GPU_buffer_lock_stream( buffer );
+ numfaces = 0;
+ }
+
+ if( draw != 0 ) {
+ if(!drawSmooth) {
+ /*if (emdm->vertexCos) {
+ VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]);
+ }
+ else {*/
+ VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n);
+ /*}*/
+ if( draw == 2 ) {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
+ }
+ else if( draw == 1 ) {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ }
+ else {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
+ }
+
+ numfaces++;
+ if( efa->v4 ) {
+ /*if (emdm->vertexCos) {
+ VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]);
+ }
+ else {*/
+ VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n);
+ /*}*/
+
+ if( draw == 2 ) {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
+ }
+ else if( draw == 1 ) {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ }
+ else {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
+ }
+
+ numfaces++;
+ }
+ }
+ else {
+ /*if (emdm->vertexCos) {
+ VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]);
+ }
+ else {*/
+ VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v1->no);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v2->no);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v3->no);
+ /*}*/
+
+ if( draw == 2 ) {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
+ }
+ else if( draw == 1 ) {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ }
+ else {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
+ }
+
+ numfaces++;
+ if( efa->v4 ) {
+ /*if (emdm->vertexCos) {
+ VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]);
+ }
+ else {*/
+ VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v3->no);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v4->no);
+
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co);
+ VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v1->no);
+ /*}*/
+
+ if( draw == 2 ) {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
+ }
+ else if( draw == 1 ) {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
+ }
+ else {
+ QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
+ QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
+ }
+
+ numfaces++;
+ }
+ }
+ }
+ prevdraw = draw;
+ }
+ GPU_buffer_unlock( buffer );
+ if( prevdraw != 0 && numfaces > 0) {
+ if( prevdraw==2 ) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
+ }
+ glDrawArrays(GL_TRIANGLES,0,numfaces*3);
+ if( prevdraw==2 ) {
+ glDisable(GL_POLYGON_STIPPLE);
+ }
+ }
+ GPU_buffer_unbind();
+ } else {
+#endif
+ dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0);
+
+#if 0
+ }
+ GPU_buffer_free( buffer, 0 );
+#endif
}
static int draw_dm_creases__setDrawOptions(void *userData, int index)
@@ -2080,7 +2451,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d,
else
sprintf(val, conv_float, VecLenf(v1, v2));
- view3d_object_text_draw_add(x, y, z, val, 0);
+ view3d_cached_text_draw_add(x, y, z, val, 0);
}
}
}
@@ -2119,7 +2490,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d,
else
sprintf(val, conv_float, area);
- view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
+ view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
}
}
}
@@ -2159,31 +2530,31 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d,
if( (e4->f & e1->f & SELECT) || (G.moving && (efa->v1->f & SELECT)) ) {
/* Vec 1 */
- sprintf(val,"%.3f", VecAngle3(v4, v1, v2));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v4, v1, v2)));
VecLerpf(fvec, efa->cent, efa->v1->co, 0.8f);
- view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
+ view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
}
if( (e1->f & e2->f & SELECT) || (G.moving && (efa->v2->f & SELECT)) ) {
/* Vec 2 */
- sprintf(val,"%.3f", VecAngle3(v1, v2, v3));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v1, v2, v3)));
VecLerpf(fvec, efa->cent, efa->v2->co, 0.8f);
- view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
+ view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
}
if( (e2->f & e3->f & SELECT) || (G.moving && (efa->v3->f & SELECT)) ) {
/* Vec 3 */
if(efa->v4)
- sprintf(val,"%.3f", VecAngle3(v2, v3, v4));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v4)));
else
- sprintf(val,"%.3f", VecAngle3(v2, v3, v1));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v1)));
VecLerpf(fvec, efa->cent, efa->v3->co, 0.8f);
- view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
+ view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
}
/* Vec 4 */
if(efa->v4) {
if( (e3->f & e4->f & SELECT) || (G.moving && (efa->v4->f & SELECT)) ) {
- sprintf(val,"%.3f", VecAngle3(v3, v4, v1));
+ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v3, v4, v1)));
VecLerpf(fvec, efa->cent, efa->v4->co, 0.8f);
- view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
+ view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
}
}
}
@@ -2254,12 +2625,99 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
}
}
else {
+ /* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
+ GPUBuffer *buffer = GPU_buffer_legacy(em->derivedFinal)?0:GPU_buffer_alloc( sizeof(float)*6*em->tottri*3*2, 0 );
+ float *varray;
+ BMFace *efa;
+ BMLoop **ls;
+ int i, curmat = 0, draw = 0;
+
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
glEnable(GL_LIGHTING);
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
- finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, em, 0);
+ if( finalDM->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
+ int prevdraw = 0, prevmat = 0;
+ int numfaces = 0;
+ int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END };
+ GPU_buffer_unlock( buffer );
+ GPU_interleaved_setup( buffer, datatype );
+ glShadeModel(GL_SMOOTH);
+ varray = GPU_buffer_lock_stream( buffer );
+ for (i=0; i<em->tottri; i++) {
+ int drawSmooth;
+
+ ls = em->looptris[i];
+ efa = ls[0]->f;
+ drawSmooth = BM_TestHFlag(efa, BM_SMOOTH);
+
+ if( !BM_TestHFlag(efa, BM_HIDDEN) ) {
+ curmat = efa->mat_nr+1;
+ draw = 1;
+ }
+ else {
+ draw = 0;
+ }
+ if( ((prevdraw != draw) || (curmat != prevmat)) && prevdraw != 0 && numfaces > 0) {
+ if( prevdraw==2 ) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
+ }
+ GPU_buffer_unlock( buffer );
+ GPU_enable_material(prevmat, NULL);
+ glDrawArrays(GL_TRIANGLES,0,numfaces*3);
+ if( prevdraw==2 ) {
+ glDisable(GL_POLYGON_STIPPLE);
+ }
+ varray = GPU_buffer_lock_stream( buffer );
+ numfaces = 0;
+ }
+ if( draw != 0 ) {
+ if(!drawSmooth) {
+ VECCOPY(&varray[numfaces*18], ls[0]->v->co);
+ VECCOPY(&varray[numfaces*18+3], efa->no);
+
+ VECCOPY(&varray[numfaces*18+6], ls[1]->v->co);
+ VECCOPY(&varray[numfaces*18+9], efa->no);
+
+ VECCOPY(&varray[numfaces*18+12], ls[2]->v->co);
+ VECCOPY(&varray[numfaces*18+15], efa->no);
+ numfaces++;
+ }
+ else {
+ VECCOPY(&varray[numfaces*18],ls[0]->v->co);
+ VECCOPY(&varray[numfaces*18+3],ls[0]->v->no);
+
+ VECCOPY(&varray[numfaces*18+6],ls[1]->v->co);
+ VECCOPY(&varray[numfaces*18+9],ls[1]->v->no);
+
+ VECCOPY(&varray[numfaces*18+12],ls[2]->v->co);
+ VECCOPY(&varray[numfaces*18+15],ls[2]->v->no);
+ numfaces++;
+ }
+ }
+ prevdraw = draw;
+ prevmat = curmat;
+ }
+ GPU_buffer_unlock( buffer );
+ if( prevdraw != 0 && numfaces > 0) {
+ if( prevdraw==2 ) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
+ }
+ GPU_enable_material(prevmat, NULL);
+ glDrawArrays(GL_TRIANGLES,0,numfaces*3);
+ if( prevdraw==2 ) {
+ glDisable(GL_POLYGON_STIPPLE);
+ }
+ }
+ GPU_buffer_unbind();
+ }
+ else {
+ finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0);
+ }
+ GPU_buffer_free(buffer,0);
glFrontFace(GL_CCW);
glDisable(GL_LIGHTING);
@@ -2390,7 +2848,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
GPU_disable_material();
}
- EM_free_index_arrays();
+ EDBM_free_index_arrays(em);
}
/* Mesh drawing routines */
@@ -3090,82 +3548,31 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
return retval;
}
-/* *********** text drawing for particles ************* */
-static ListBase pstrings= {NULL, NULL};
-
-typedef struct ViewParticleString {
- struct ViewParticleString *next, *prev;
- float vec[3], col[4];
- char str[128];
- short mval[2];
- short xoffs;
-} ViewParticleString;
-
-
-void view3d_particle_text_draw_add(float x, float y, float z, char *str, short xoffs)
-{
- ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString");
-
- BLI_addtail(&pstrings, vos);
- BLI_strncpy(vos->str, str, 128);
- vos->vec[0]= x;
- vos->vec[1]= y;
- vos->vec[2]= z;
- glGetFloatv(GL_CURRENT_COLOR, vos->col);
- vos->xoffs= xoffs;
-}
-
-static void view3d_particle_text_draw(View3D *v3d, ARegion *ar)
+/* *********** drawing for particles ************* */
+static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int select)
{
- ViewObjectString *vos;
- int tot= 0;
-
- /* project first and test */
- for(vos= pstrings.first; vos; vos= vos->next) {
- project_short(ar, vos->vec, vos->mval);
- if(vos->mval[0]!=IS_CLIPPED)
- tot++;
- }
-
- if(tot) {
- RegionView3D *rv3d= ar->regiondata;
- int a;
-
- if(rv3d->rflag & RV3D_CLIPPING)
- for(a=0; a<6; a++)
- glDisable(GL_CLIP_PLANE0+a);
-
- wmPushMatrix();
- ED_region_pixelspace(ar);
-
- if(v3d->zbuf) glDepthMask(0);
-
- for(vos= pstrings.first; vos; vos= vos->next) {
- if(vos->mval[0]!=IS_CLIPPED) {
- glColor3fv(vos->col);
- BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 2.0, vos->str);
- }
- }
-
- if(v3d->zbuf) glDepthMask(1);
-
- wmPopMatrix();
+ /* draw created data arrays */
+ switch(draw_as){
+ case PART_DRAW_AXIS:
+ case PART_DRAW_CROSS:
+ glDrawArrays(GL_LINES, 0, 6*totpoint);
+ break;
+ case PART_DRAW_LINE:
+ glDrawArrays(GL_LINES, 0, 2*totpoint);
+ break;
+ case PART_DRAW_BB:
+ if(ob_dt<=OB_WIRE || select)
+ glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
+ else
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- if(rv3d->rflag & RV3D_CLIPPING)
- for(a=0; a<6; a++)
- glEnable(GL_CLIP_PLANE0+a);
+ glDrawArrays(GL_QUADS, 0, 4*totpoint);
+ break;
+ default:
+ glDrawArrays(GL_POINTS, 0, totpoint);
+ break;
}
-
- if(pstrings.first)
- BLI_freelistN(&pstrings);
}
-typedef struct ParticleDrawData {
- float *vdata, *vd;
- float *ndata, *nd;
- float *cdata, *cd;
- float *vedata, *ved;
- float *ma_r, *ma_g, *ma_b;
-} ParticleDrawData;
static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd)
{
float vec[3], vec2[3];
@@ -3208,7 +3615,7 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
cd[7]=cd[10]=1.0;
cd[13]=cd[12]=cd[15]=cd[16]=0.0;
cd[14]=cd[17]=1.0;
- cd+=18;
+ pdd->cd+=18;
VECCOPY(vec2,state->co);
}
@@ -3330,7 +3737,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
ParticleData *pars, *pa;
ParticleKey state, *states=0;
ParticleBillboardData bb;
- ParticleDrawData pdd;
+ ParticleSimulationData sim = {scene, ob, psys, NULL};
+ ParticleDrawData *pdd = psys->pdd;
Material *ma;
float vel[3], imat[4][4];
float timestep, pixsize=1.0, pa_size, r_tilt, r_length;
@@ -3358,12 +3766,20 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART)==0)
return;
- if(part->draw_as==PART_DRAW_NOT) return;
+ if(part->draw_as == PART_DRAW_REND)
+ draw_as = part->ren_as;
+ else
+ draw_as = part->draw_as;
+
+ if(draw_as == PART_DRAW_NOT)
+ return;
/* 2. */
+ sim.psmd = psmd = psys_get_modifier(ob,psys);
+
if(part->phystype==PART_PHYS_KEYED){
if(psys->flag&PSYS_KEYED){
- psys_count_keyed_targets(ob,psys);
+ psys_count_keyed_targets(&sim);
if(psys->totkeyed==0)
return;
}
@@ -3381,34 +3797,28 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
totchild=0;
else
totchild=psys->totchild*part->disp/100;
-
- memset(&pdd, 0, sizeof(ParticleDrawData));
ma= give_current_material(ob,part->omat);
if(v3d->zbuf) glDepthMask(1);
- if(select)
- cpack(0xFFFFFF);
- else if((ma) && (part->draw&PART_DRAW_MAT_COL)) {
+ if((ma) && (part->draw&PART_DRAW_MAT_COL)) {
glColor3f(ma->r,ma->g,ma->b);
ma_r = ma->r;
ma_g = ma->g;
ma_b = ma->b;
-
- pdd.ma_r = &ma_r;
- pdd.ma_g = &ma_g;
- pdd.ma_b = &ma_b;
-
- create_cdata = 1;
}
else
cpack(0);
- psmd= psys_get_modifier(ob,psys);
+ if(pdd) {
+ pdd->ma_r = &ma_r;
+ pdd->ma_g = &ma_g;
+ pdd->ma_b = &ma_b;
+ }
- timestep= psys_get_timestep(part);
+ timestep= psys_get_timestep(&sim);
if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
float mat[4][4];
@@ -3418,11 +3828,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
totpart=psys->totpart;
- if(part->draw_as==PART_DRAW_REND)
- draw_as = part->ren_as;
- else
- draw_as = part->draw_as;
-
//if(part->flag&PART_GLOB_TIME)
cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f);
@@ -3452,6 +3857,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
pixsize*=2.0;
else
pixsize*=part->draw_size;
+
+ if(draw_as==PART_DRAW_AXIS)
+ create_cdata = 1;
break;
case PART_DRAW_OB:
if(part->dup_ob==0)
@@ -3499,57 +3907,73 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
Normalize(imat[1]);
}
+ if(!create_cdata && pdd && pdd->cdata) {
+ MEM_freeN(pdd->cdata);
+ pdd->cdata = pdd->cd = NULL;
+ }
+
/* 4. */
- if(draw_as && draw_as!=PART_DRAW_PATH) {
+ if(draw_as && ELEM(draw_as, PART_DRAW_PATH, PART_DRAW_CIRC)==0) {
int tot_vec_size = (totpart + totchild) * 3 * sizeof(float);
-
+ int create_ndata = 0;
+
+ if(!pdd)
+ pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticlDrawData");
+
if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
tot_vec_size *= part->trail_count;
psys_make_temp_pointcache(ob, psys);
}
- if(draw_as!=PART_DRAW_CIRC) {
- switch(draw_as) {
- case PART_DRAW_AXIS:
- case PART_DRAW_CROSS:
- if(draw_as != PART_DRAW_CROSS || create_cdata)
- pdd.cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata");
- pdd.vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata");
- break;
- case PART_DRAW_LINE:
- if(create_cdata)
- pdd.cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata");
- pdd.vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata");
- break;
- case PART_DRAW_BB:
- if(create_cdata)
- pdd.cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata");
- pdd.vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
- pdd.ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
- break;
- default:
- if(create_cdata)
- pdd.cdata=MEM_callocN(tot_vec_size, "particle_cdata");
- pdd.vdata=MEM_callocN(tot_vec_size, "particle_vdata");
- }
+ switch(draw_as) {
+ case PART_DRAW_AXIS:
+ case PART_DRAW_CROSS:
+ tot_vec_size *= 6;
+ if(draw_as != PART_DRAW_CROSS)
+ create_cdata = 1;
+ break;
+ case PART_DRAW_LINE:
+ tot_vec_size *= 2;
+ break;
+ case PART_DRAW_BB:
+ tot_vec_size *= 4;
+ create_ndata = 1;
+ break;
}
+ if(pdd->tot_vec_size != tot_vec_size)
+ psys_free_pdd(psys);
+
+ if(!pdd->vdata)
+ pdd->vdata = MEM_callocN(tot_vec_size, "particle_vdata");
+ if(create_cdata && !pdd->cdata)
+ pdd->cdata = MEM_callocN(tot_vec_size, "particle_cdata");
+ if(create_ndata && !pdd->ndata)
+ pdd->ndata = MEM_callocN(tot_vec_size, "particle_vdata");
+
if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) {
- pdd.vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata");
+ if(!pdd->vedata)
+ pdd->vedata = MEM_callocN(2 * (totpart + totchild) * 3 * sizeof(float), "particle_vedata");
+
need_v = 1;
}
- pdd.vd= pdd.vdata;
- pdd.ved= pdd.vedata;
- pdd.cd= pdd.cdata;
- pdd.nd= pdd.ndata;
-
- psys->lattice= psys_get_lattice(scene, ob, psys);
+ pdd->vd= pdd->vdata;
+ pdd->ved= pdd->vedata;
+ pdd->cd= pdd->cdata;
+ pdd->nd= pdd->ndata;
+ pdd->tot_vec_size= tot_vec_size;
}
- if(draw_as){
+ psys->lattice= psys_get_lattice(&sim);
+
+ if(pdd && draw_as!=PART_DRAW_PATH){
/* 5. */
- for(a=0,pa=pars; a<totpart+totchild; a++, pa++){
+ if((pdd->flag & PARTICLE_DRAW_DATA_UPDATED)
+ && (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) {
+ totpoint = pdd->totpoint; /* draw data is up to date */
+ }
+ else for(a=0,pa=pars; a<totpart+totchild; a++, pa++){
/* setup per particle individual stuff */
if(a<totpart){
if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
@@ -3559,9 +3983,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
pa_birthtime=pa->time;
pa_dietime = pa->dietime;
pa_size=pa->size;
- if(part->phystype==PART_PHYS_BOIDS) {
+ if(part->phystype==PART_PHYS_BOIDS)
pa_health = pa->boid->data.health;
- }
else
pa_health = -1.0;
@@ -3596,10 +4019,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
#endif // XXX old animation system
- BLI_srandom(psys->seed+a);
-
- r_tilt = 2.0f*(BLI_frand() - 0.5f);
- r_length = BLI_frand();
+ r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
+ r_length = PSYS_FRAND(a + 22);
}
else{
ChildParticle *cpa= &psys->child[a-totpart];
@@ -3630,160 +4051,143 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
pa_health = -1.0;
- r_tilt = 2.0f * cpa->rand[2];
- r_length = cpa->rand[1];
+ r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
+ r_length = PSYS_FRAND(a + 22);
}
- if(draw_as!=PART_DRAW_PATH){
- drawn = 0;
- if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
- float length = part->path_end * (1.0 - part->randlength * r_length);
- int trail_count = part->trail_count * (1.0 - part->randlength * r_length);
- float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length;
- float dt = length / (trail_count ? (float)trail_count : 1.0f);
- int i=0;
-
- ct+=dt;
- for(i=0; i < trail_count; i++, ct += dt) {
- if(part->draw & PART_ABS_PATH_TIME) {
- if(ct < pa_birthtime || ct > pa_dietime)
- continue;
- }
- else if(ct < 0.0f || ct > 1.0f)
+ drawn = 0;
+ if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
+ float length = part->path_end * (1.0 - part->randlength * r_length);
+ int trail_count = part->trail_count * (1.0 - part->randlength * r_length);
+ float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length;
+ float dt = length / (trail_count ? (float)trail_count : 1.0f);
+ int i=0;
+
+ ct+=dt;
+ for(i=0; i < trail_count; i++, ct += dt) {
+ if(part->draw & PART_ABS_PATH_TIME) {
+ if(ct < pa_birthtime || ct > pa_dietime)
continue;
+ }
+ else if(ct < 0.0f || ct > 1.0f)
+ continue;
- state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime));
- psys_get_particle_on_path(scene,ob,psys,a,&state,need_v);
-
- if(psys->parent)
- Mat4MulVecfl(psys->parent->obmat, state.co);
-
- /* create actiual particle data */
- if(draw_as == PART_DRAW_BB) {
- bb.size = pa_size;
- bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
- bb.time = ct;
- }
+ state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime));
+ psys_get_particle_on_path(&sim,a,&state,need_v);
+
+ if(psys->parent)
+ Mat4MulVecfl(psys->parent->obmat, state.co);
+
+ /* create actiual particle data */
+ if(draw_as == PART_DRAW_BB) {
+ bb.size = pa_size;
+ bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
+ bb.time = ct;
+ }
- draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd);
+ draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd);
- totpoint++;
- drawn = 1;
- }
+ totpoint++;
+ drawn = 1;
}
- else
- {
- state.time=cfra;
- if(psys_get_particle_state(scene,ob,psys,a,&state,0)){
- if(psys->parent)
- Mat4MulVecfl(psys->parent->obmat, state.co);
-
- /* create actiual particle data */
- if(draw_as == PART_DRAW_BB) {
- bb.size = pa_size;
- bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
- bb.time = pa_time;
- }
+ }
+ else
+ {
+ state.time=cfra;
+ if(psys_get_particle_state(&sim,a,&state,0)){
+ if(psys->parent)
+ Mat4MulVecfl(psys->parent->obmat, state.co);
+
+ /* create actiual particle data */
+ if(draw_as == PART_DRAW_BB) {
+ bb.size = pa_size;
+ bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
+ bb.time = pa_time;
+ }
- draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd);
+ draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd);
- totpoint++;
- drawn = 1;
- }
+ totpoint++;
+ drawn = 1;
}
+ }
- if(drawn) {
- /* additional things to draw for each particle */
- /* (velocity, size and number) */
- if(pdd.vedata){
- VECCOPY(pdd.ved,state.co);
- pdd.ved+=3;
- VECCOPY(vel,state.vel);
- VecMulf(vel,timestep);
- VECADD(pdd.ved,state.co,vel);
- pdd.ved+=3;
-
- totve++;
- }
+ if(drawn) {
+ /* additional things to draw for each particle */
+ /* (velocity, size and number) */
+ if(pdd->vedata){
+ VECCOPY(pdd->ved,state.co);
+ pdd->ved+=3;
+ VECCOPY(vel,state.vel);
+ VecMulf(vel,timestep);
+ VECADD(pdd->ved,state.co,vel);
+ pdd->ved+=3;
+
+ totve++;
+ }
- if(part->draw & PART_DRAW_SIZE){
- setlinestyle(3);
- drawcircball(GL_LINE_LOOP, state.co, pa_size, imat);
- setlinestyle(0);
- }
+ if(part->draw & PART_DRAW_SIZE){
+ setlinestyle(3);
+ drawcircball(GL_LINE_LOOP, state.co, pa_size, imat);
+ setlinestyle(0);
+ }
- if((part->draw&PART_DRAW_NUM || part->draw&PART_DRAW_HEALTH) && !(G.f & G_RENDER_SHADOW)){
- val[0]= '\0';
-
- if(part->draw&PART_DRAW_NUM)
- sprintf(val, " %i", a);
+ if((part->draw&PART_DRAW_NUM || part->draw&PART_DRAW_HEALTH) && !(G.f & G_RENDER_SHADOW)){
+ val[0]= '\0';
+
+ if(part->draw&PART_DRAW_NUM)
+ sprintf(val, " %i", a);
- if(part->draw&PART_DRAW_NUM && part->draw&PART_DRAW_HEALTH)
- sprintf(val, "%s:", val);
+ if(part->draw&PART_DRAW_NUM && part->draw&PART_DRAW_HEALTH)
+ sprintf(val, "%s:", val);
- if(part->draw&PART_DRAW_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS)
- sprintf(val, "%s %.2f", val, pa_health);
+ if(part->draw&PART_DRAW_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS)
+ sprintf(val, "%s %.2f", val, pa_health);
- /* in path drawing state.co is the end point */
- view3d_particle_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0);
- }
+ /* in path drawing state.co is the end point */
+ view3d_cached_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0);
}
}
}
+ }
/* 6. */
- glGetIntegerv(GL_POLYGON_MODE, polygonmode);
- glDisableClientState(GL_NORMAL_ARRAY);
-
- if(draw_as==PART_DRAW_PATH){
- ParticleCacheKey **cache, *path;
- float *cd2=0,*cdata2=0;
+ glGetIntegerv(GL_POLYGON_MODE, polygonmode);
+ glDisableClientState(GL_NORMAL_ARRAY);
- glEnableClientState(GL_VERTEX_ARRAY);
+ if(draw_as==PART_DRAW_PATH){
+ ParticleCacheKey **cache, *path;
+ float *cd2=0,*cdata2=0;
- /* setup gl flags */
- if(ob_dt > OB_WIRE) {
- glEnableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
- if(part->draw&PART_DRAW_MAT_COL)
- glEnableClientState(GL_COLOR_ARRAY);
-
- glEnable(GL_LIGHTING);
- glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
- }
- else {
- glDisableClientState(GL_NORMAL_ARRAY);
+ /* setup gl flags */
+ if(ob_dt > OB_WIRE) {
+ glEnableClientState(GL_NORMAL_ARRAY);
- glDisable(GL_COLOR_MATERIAL);
- glDisable(GL_LIGHTING);
- UI_ThemeColor(TH_WIRE);
- }
+ if(part->draw&PART_DRAW_MAT_COL)
+ glEnableClientState(GL_COLOR_ARRAY);
- if(totchild && (part->draw&PART_DRAW_PARENT)==0)
- totpart=0;
+ glEnable(GL_LIGHTING);
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+ }
+ else {
+ glDisableClientState(GL_NORMAL_ARRAY);
- /* draw actual/parent particles */
- cache=psys->pathcache;
- for(a=0, pa=psys->particles; a<totpart; a++, pa++){
- path=cache[a];
- if(path->steps > 0) {
- glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
+ glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_LIGHTING);
+ UI_ThemeColor(TH_WIRE);
+ }
- if(ob_dt > OB_WIRE) {
- glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
- if(part->draw&PART_DRAW_MAT_COL)
- glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
- }
+ if(totchild && (part->draw&PART_DRAW_PARENT)==0)
+ totpart=0;
- glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
- }
- }
-
- /* draw child particles */
- cache=psys->childcache;
- for(a=0; a<totchild; a++){
- path=cache[a];
+ /* draw actual/parent particles */
+ cache=psys->pathcache;
+ for(a=0, pa=psys->particles; a<totpart; a++, pa++){
+ path=cache[a];
+ if(path->steps > 0) {
glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
if(ob_dt > OB_WIRE) {
@@ -3794,83 +4198,103 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
}
+ }
+
+ /* draw child particles */
+ cache=psys->childcache;
+ for(a=0; a<totchild; a++){
+ path=cache[a];
+ glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
-
- /* restore & clean up */
if(ob_dt > OB_WIRE) {
+ glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
if(part->draw&PART_DRAW_MAT_COL)
- glDisable(GL_COLOR_ARRAY);
- glDisable(GL_COLOR_MATERIAL);
+ glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
}
- if(cdata2)
- MEM_freeN(cdata2);
- cd2=cdata2=0;
+ glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
+ }
+
- glLineWidth(1.0f);
+ /* restore & clean up */
+ if(ob_dt > OB_WIRE) {
+ if(part->draw&PART_DRAW_MAT_COL)
+ glDisable(GL_COLOR_ARRAY);
+ glDisable(GL_COLOR_MATERIAL);
}
- else if(draw_as!=PART_DRAW_CIRC){
- glDisableClientState(GL_COLOR_ARRAY);
- /* setup created data arrays */
- if(pdd.vdata){
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, pdd.vdata);
- }
+ if(cdata2)
+ MEM_freeN(cdata2);
+ cd2=cdata2=0;
+
+ glLineWidth(1.0f);
+ }
+ else if(pdd && ELEM(draw_as, 0, PART_DRAW_CIRC)==0){
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ /* enable point data array */
+ if(pdd->vdata){
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, pdd->vdata);
+ }
+ else
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ if(select) {
+ UI_ThemeColor(TH_ACTIVE);
+
+ if(part->draw_size)
+ glPointSize(part->draw_size + 2);
else
- glDisableClientState(GL_VERTEX_ARRAY);
+ glPointSize(4.0);
- /* billboards are drawn this way */
- if(pdd.ndata && ob_dt>OB_WIRE){
- glEnableClientState(GL_NORMAL_ARRAY);
- glNormalPointer(GL_FLOAT, 0, pdd.ndata);
- glEnable(GL_LIGHTING);
- }
- else{
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisable(GL_LIGHTING);
- }
+ glLineWidth(3.0);
- if(pdd.cdata){
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(3, GL_FLOAT, 0, pdd.cdata);
- }
+ draw_particle_arrays(draw_as, totpoint, ob_dt, 1);
+ }
- /* draw created data arrays */
- switch(draw_as){
- case PART_DRAW_AXIS:
- case PART_DRAW_CROSS:
- glDrawArrays(GL_LINES, 0, 6*totpoint);
- break;
- case PART_DRAW_LINE:
- glDrawArrays(GL_LINES, 0, 2*totpoint);
- break;
- case PART_DRAW_BB:
- if(ob_dt<=OB_WIRE)
- glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
-
- glDrawArrays(GL_QUADS, 0, 4*totpoint);
- break;
- default:
- glDrawArrays(GL_POINTS, 0, totpoint);
- break;
- }
+ /* restore from select */
+ glColor3f(ma_r,ma_g,ma_b);
+ glPointSize(part->draw_size ? part->draw_size : 2.0);
+ glLineWidth(1.0);
+
+ /* enable other data arrays */
+
+ /* billboards are drawn this way */
+ if(pdd->ndata && ob_dt>OB_WIRE){
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer(GL_FLOAT, 0, pdd->ndata);
+ glEnable(GL_LIGHTING);
+ }
+ else{
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisable(GL_LIGHTING);
}
- if(pdd.vedata){
- glDisableClientState(GL_COLOR_ARRAY);
- cpack(0xC0C0C0);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, pdd.vedata);
-
- glDrawArrays(GL_LINES, 0, 2*totve);
+ if(pdd->cdata){
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
}
- glPolygonMode(GL_FRONT, polygonmode[0]);
- glPolygonMode(GL_BACK, polygonmode[1]);
+ draw_particle_arrays(draw_as, totpoint, ob_dt, 0);
+
+ pdd->flag |= PARTICLE_DRAW_DATA_UPDATED;
+ pdd->totpoint = totpoint;
+ }
+
+ if(pdd && pdd->vedata){
+ glDisableClientState(GL_COLOR_ARRAY);
+ cpack(0xC0C0C0);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, pdd->vedata);
+
+ glDrawArrays(GL_LINES, 0, 2*totve);
}
+ glPolygonMode(GL_FRONT, polygonmode[0]);
+ glPolygonMode(GL_BACK, polygonmode[1]);
+
/* 7. */
glDisable(GL_LIGHTING);
@@ -3879,17 +4303,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(states)
MEM_freeN(states);
- if(pdd.vdata)
- MEM_freeN(pdd.vdata);
- if(pdd.vedata)
- MEM_freeN(pdd.vedata);
- if(pdd.cdata)
- MEM_freeN(pdd.cdata);
- if(pdd.ndata)
- MEM_freeN(pdd.ndata);
psys->flag &= ~PSYS_DRAWING;
+ /* draw data can't be saved for billboards as they must update to target changes */
+ if(draw_as == PART_DRAW_BB) {
+ psys_free_pdd(psys);
+ pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED;
+ }
+
if(psys->lattice){
end_latt_deform(psys->lattice);
psys->lattice= NULL;
@@ -3913,10 +4335,8 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj
float *pathcol = NULL, *pcol;
- if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) {
+ if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED)
PE_update_object(scene, ob, 0);
- edit->psys->flag &= ~PSYS_HAIR_UPDATED;
- }
/* create path and child path cache if it doesn't exist already */
if(edit->pathcache==0)
@@ -3990,7 +4410,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj
if(!(point->flag & PEP_HIDE))
totkeys += point->totkey;
- if(!(edit->points->keys->flag & PEK_USE_WCO))
+ if(edit->points && !(edit->points->keys->flag & PEK_USE_WCO))
pd=pdata=MEM_callocN(totkeys*3*sizeof(float), "particle edit point data");
cd=cdata=MEM_callocN(totkeys*(timed?4:3)*sizeof(float), "particle edit color data");
@@ -4947,8 +5367,9 @@ static void drawtexspace(Object *ob)
}
/* draws wire outline */
-static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void drawSolidSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
{
+ RegionView3D *rv3d= ar->regiondata;
Object *ob= base->object;
glLineWidth(2.0);
@@ -4967,7 +5388,7 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
}
else if(ob->type==OB_ARMATURE) {
if(!(ob->mode & OB_MODE_POSE))
- draw_armature(scene, v3d, rv3d, base, OB_WIRE, 0);
+ draw_armature(scene, v3d, ar, base, OB_WIRE, 0);
}
glLineWidth(1.0);
@@ -5077,11 +5498,11 @@ void drawRBpivot(bRigidBodyJointConstraint *data)
glVertex3fv(v);
glEnd();
if (axis==0)
- view3d_object_text_draw_add(v[0], v[1], v[2], "px", 0);
+ view3d_cached_text_draw_add(v[0], v[1], v[2], "px", 0);
else if (axis==1)
- view3d_object_text_draw_add(v[0], v[1], v[2], "py", 0);
+ view3d_cached_text_draw_add(v[0], v[1], v[2], "py", 0);
else
- view3d_object_text_draw_add(v[0], v[1], v[2], "pz", 0);
+ view3d_cached_text_draw_add(v[0], v[1], v[2], "pz", 0);
}
glLineWidth (1.0f);
setlinestyle(0);
@@ -5124,6 +5545,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
}
}
+ /* no return after this point, otherwise leaks */
+ view3d_cached_text_draw_begin();
+
/* draw keys? */
#if 0 // XXX old animation system
if(base==(scene->basact) || (base->flag & (SELECT+BA_WAS_SEL))) {
@@ -5206,11 +5630,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
/* draw paths... */
// TODO...
- /* multiply view with object matrix */
- wmMultMatrix(ob->obmat);
- /* local viewmat and persmat, to calculate projections */
- wmGetMatrix(rv3d->viewmatob);
- wmGetSingleMatrix(rv3d->persmatob);
+ /* multiply view with object matrix.
+ * local viewmat and persmat, to calculate projections */
+ ED_view3d_init_mats_rv3d(ob, rv3d);
/* which wire color */
if((flag & DRAW_CONSTCOLOR) == 0) {
@@ -5267,7 +5689,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
if(ob==OBACT && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))) {
if(ob->type==OB_MESH) {
- if(ob==scene->obedit);
+ if(ob->mode & OB_MODE_EDIT);
else {
if(dt<OB_SOLID)
zbufoff= 1;
@@ -5289,7 +5711,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
if(dt>=OB_BOUNDBOX ) {
dtx= ob->dtx;
- if(scene->obedit==ob) {
+ if(ob->mode & OB_MODE_EDIT) {
// the only 2 extra drawtypes alowed in editmode
dtx= dtx & (OB_DRAWWIRE|OB_TEXSPACE);
}
@@ -5305,20 +5727,18 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
/* draw outline for selected solid objects, mesh does itself */
if((v3d->flag & V3D_SELECT_OUTLINE) && ob->type!=OB_MESH) {
- if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=scene->obedit && (flag && DRAW_SCENESET)==0) {
+ if(dt>OB_WIRE && dt<OB_TEXTURE && (ob->mode & OB_MODE_EDIT)==0 && (flag & DRAW_SCENESET)==0) {
if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) {
- drawSolidSelect(scene, v3d, rv3d, base);
+ drawSolidSelect(scene, v3d, ar, base);
}
}
}
switch( ob->type) {
case OB_MESH:
- if (!(base->flag&OB_RADIO)) {
- empty_object= draw_mesh_object(scene, v3d, rv3d, base, dt, flag);
- if(flag!=DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself
- }
+ empty_object= draw_mesh_object(scene, v3d, rv3d, base, dt, flag);
+ if(flag!=DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself
break;
case OB_FONT:
@@ -5454,7 +5874,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
break;
case OB_ARMATURE:
if(dt>OB_WIRE) GPU_enable_material(0, NULL); // we use default material
- empty_object= draw_armature(scene, v3d, rv3d, base, dt, flag);
+ empty_object= draw_armature(scene, v3d, ar, base, dt, flag);
if(dt>OB_WIRE) GPU_disable_material();
break;
default:
@@ -5474,10 +5894,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
wmLoadMatrix(rv3d->viewmat);
+ view3d_cached_text_draw_begin();
+
for(psys=ob->particlesystem.first; psys; psys=psys->next)
draw_new_particle_system(scene, v3d, rv3d, base, psys, dt);
- view3d_particle_text_draw(v3d, ar);
+ view3d_cached_text_draw_end(v3d, ar, 0, NULL);
wmMultMatrix(ob->obmat);
@@ -5629,7 +6051,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
/* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */
/* but, we also dont draw names for sets or duplicators */
if(flag == 0) {
- view3d_object_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10);
+ view3d_cached_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10);
}
}
/*if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/
@@ -5652,14 +6074,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
}
/* return warning, this is cached text draw */
- view3d_object_text_draw(v3d, ar);
+ view3d_cached_text_draw_end(v3d, ar, 1, NULL);
wmLoadMatrix(rv3d->viewmat);
if(zbufoff) glDisable(GL_DEPTH_TEST);
if(warning_recursive) return;
- if(base->flag & (OB_FROMDUPLI|OB_RADIO)) return;
+ if(base->flag & OB_FROMDUPLI) return;
if(G.f & G_RENDER_SHADOW) return;
/* object centers, need to be drawn in viewmat space for speed, but OK for picking select */
@@ -5851,6 +6273,16 @@ static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmoot
return 0;
if (!(me->mpoly[index].flag&ME_HIDE)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+static int bbs_mesh_solid__setDrawOpts_legacy(void *userData, int index, int *drawSmooth_r)
+{
+ Mesh *me = userData;
+
+ if (!(me->mface[index].flag&ME_HIDE)) {
WM_set_framebuffer_index_color(index+1);
return 1;
} else {
@@ -5863,9 +6295,41 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob)
{
DerivedMesh *dm = mesh_get_derived_final(scene, ob, v3d->customdata_mask);
Mesh *me = (Mesh*)ob->data;
+ MCol *colors;
+ int i,j;
glColor3ub(0, 0, 0);
- dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0);
+
+ if( !GPU_buffer_legacy(dm) ) {
+ int *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+ int ind;
+ colors = MEM_mallocN(dm->getNumTessFaces(dm)*sizeof(MCol)*4,"bbs_mesh_solid");
+ for(i=0;i<dm->getNumFaces(dm);i++) {
+ if( index != 0 )
+ ind = index[i];
+ else
+ ind = i;
+ if (!(me->mface[ind].flag&ME_HIDE)) {
+ unsigned int fbindex = index_to_framebuffer(ind+1);
+ for(j=0;j<4;j++) {
+ colors[i*4+j].b = ((fbindex)&0xFF);
+ colors[i*4+j].g = (((fbindex)>>8)&0xFF);
+ colors[i*4+j].r = (((fbindex)>>16)&0xFF);
+ }
+ }
+ else {
+ memset(&colors[i*4],0,sizeof(MCol)*4);
+ }
+ }
+
+ CustomData_add_layer( &dm->faceData, CD_ID_MCOL, CD_ASSIGN, colors, dm->numFaceData );
+ GPU_buffer_free(dm->drawObject->colors,0);
+ dm->drawObject->colors = 0;
+ dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 1);
+ }
+ else {
+ dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts_legacy, me, 0);
+ }
dm->release(dm);
}
@@ -5882,7 +6346,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
switch( ob->type) {
case OB_MESH:
{
- if(ob == scene->obedit) {
+ if(ob->mode & OB_MODE_EDIT) {
Mesh *me= ob->data;
BMEditMesh *em= me->edit_btmesh;
@@ -5938,7 +6402,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
DerivedMesh *dm=NULL, *edm=NULL;
int glsl;
- if(ob == scene->obedit)
+ if(ob->mode & OB_MODE_EDIT)
edm= editbmesh_get_derived_base(ob, me->edit_btmesh);
else
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index 0bdc65b5461..ef3627e2b12 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -169,7 +169,6 @@ static int larger_pow2(int n)
void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow)
{
- Object *ob = base->object;
RegionView3D *rv3d= ar->regiondata;
float viewnormal[3];
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index b5e5de928b5..2cade9bb685 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -158,6 +158,24 @@ RegionView3D *ED_view3d_context_rv3d(bContext *C)
return rv3d;
}
+/* Most of the time this isn't needed since you could assume the view matrix was
+ * set while drawing, however when functions like mesh_foreachScreenVert are
+ * called by selection tools, we can't be sure this object was the last.
+ *
+ * for example, transparent objects are drawn after editmode and will cause
+ * the rv3d mat's to change and break selection.
+ *
+ * 'ED_view3d_init_mats_rv3d' should be called before
+ * view3d_project_short_clip and view3d_project_short_noclip in cases where
+ * these functions are not used during draw_object
+ */
+void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
+{
+ wmMultMatrix(ob->obmat);
+ /* local viewmat and persmat, to calculate projections */
+ wmGetMatrix(rv3d->viewmatob);
+ wmGetSingleMatrix(rv3d->persmatob);
+}
/* ******************** default callbacks for view3d space ***************** */
@@ -259,7 +277,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
if(v3do->localvd) {
v3do->localvd= NULL;
v3do->properties_storage= NULL;
- v3do->localview= 0;
v3do->lay= v3dn->localvd->lay;
v3do->lay &= 0xFFFFFF;
}
@@ -275,101 +292,69 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
return (SpaceLink *)v3dn;
}
-static void view3d_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype)
-{
- RegionView3D *rv3d= ar->regiondata;
- ListBase *keymap;
-
- /* copy last mode, then we can re-init the region maps */
- rv3d->lastmode= stype;
-
- keymap= WM_keymap_listbase(wm, "Object Mode", 0, 0);
- if(ELEM(stype, 0, NS_MODE_OBJECT))
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0);
- if(stype==NS_EDITMODE_MESH)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Curve", 0, 0);
- if(stype==NS_EDITMODE_CURVE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Armature", 0, 0);
- if(stype==NS_EDITMODE_ARMATURE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Pose", 0, 0);
- if(stype==NS_MODE_POSE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Metaball", 0, 0);
- if(stype==NS_EDITMODE_MBALL)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Lattice", 0, 0);
- if(stype==NS_EDITMODE_LATTICE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- /* armature sketching needs to take over mouse */
- keymap= WM_keymap_listbase(wm, "Armature_Sketch", 0, 0);
- if(stype==NS_EDITMODE_ARMATURE)
- WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- keymap= WM_keymap_listbase(wm, "Particle", 0, 0);
- if(stype==NS_MODE_PARTICLE)
- WM_event_add_keymap_handler(&ar->handlers, keymap);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-
- /* editfont keymap swallows all... */
- keymap= WM_keymap_listbase(wm, "Font", 0, 0);
- if(stype==NS_EDITMODE_TEXT)
- WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10);
- else
- WM_event_remove_keymap_handler(&ar->handlers, keymap);
-}
-
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
{
- RegionView3D *rv3d= ar->regiondata;
- ListBase *keymap;
+ wmKeyMap *keymap;
+
+ /* object ops. */
+
+ /* pose is not modal, operator poll checks for this */
+ keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* own keymap */
- keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ keymap= WM_keymap_find(wm->defaultconf, "Object Mode", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Vertex Paint", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Weight Paint", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Sculpt", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* object ops. */
- keymap= WM_keymap_listbase(wm, "Object Non-modal", 0, 0);
+ keymap= WM_keymap_find(wm->defaultconf, "EditMesh", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* pose is not modal, operator poll checks for this */
- keymap= WM_keymap_listbase(wm, "Pose", 0, 0);
+ keymap= WM_keymap_find(wm->defaultconf, "Curve", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Armature", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Metaball", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
- /* modal ops keymaps */
- view3d_modal_keymaps(wm, ar, rv3d->lastmode);
- /* operator poll checks for modes */
- keymap= WM_keymap_listbase(wm, "ImagePaint", 0, 0);
+ keymap= WM_keymap_find(wm->defaultconf, "Lattice", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ /* armature sketching needs to take over mouse */
+ keymap= WM_keymap_find(wm->defaultconf, "Armature_Sketch", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Particle", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ /* editfont keymap swallows all... */
+ keymap= WM_keymap_find(wm->defaultconf, "Font", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Object Non-modal", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ /* own keymap, last so modes can override it */
+ keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap= WM_keymap_find(wm->defaultconf, "View3D", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -444,7 +429,6 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
ED_region_tag_redraw(ar);
break;
case ND_MODE:
- view3d_modal_keymaps(wmn->wm, ar, wmn->subtype);
ED_region_tag_redraw(ar);
break;
}
@@ -454,6 +438,7 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
case ND_BONE_ACTIVE:
case ND_BONE_SELECT:
case ND_TRANSFORM:
+ case ND_POSE:
case ND_DRAW:
case ND_MODIFIER:
case ND_CONSTRAINT:
@@ -482,12 +467,21 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
ED_region_tag_redraw(ar);
break;
}
+ break;
+ case NC_WORLD:
+ switch(wmn->data) {
+ case ND_WORLD_DRAW:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
case NC_LAMP:
switch(wmn->data) {
case ND_LIGHTING_DRAW:
ED_region_tag_redraw(ar);
break;
}
+ break;
case NC_IMAGE:
/* this could be more fine grained checks if we had
* more context than just the region */
@@ -516,7 +510,7 @@ static void view3d_main_area_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -552,11 +546,11 @@ static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn)
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
- keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -594,6 +588,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
case ND_BONE_ACTIVE:
case ND_BONE_SELECT:
case ND_TRANSFORM:
+ case ND_POSE:
case ND_DRAW:
case ND_KEYS:
ED_region_tag_redraw(ar);
@@ -608,6 +603,10 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
break;
}
break;
+ case NC_BRUSH:
+ if(wmn->action==NA_EDITED)
+ ED_region_tag_redraw(ar);
+ break;
case NC_SPACE:
if(wmn->data == ND_SPACE_VIEW3D)
ED_region_tag_redraw(ar);
@@ -618,16 +617,14 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
/* add handlers, stuff you only do once or on area/region changes */
static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar)
{
- ListBase *keymap;
+ wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
- keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
+ keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
-
-
static void view3d_tools_area_draw(const bContext *C, ARegion *ar)
{
ED_region_panels(C, ar, 1, CTX_data_mode_string(C), -1);
@@ -642,10 +639,10 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
if(CTX_data_dir(member)) {
static const char *dir[] = {
- "selected_objects", "selected_bases" "selected_editable_objects",
- "selected_editable_bases" "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
+ "selected_objects", "selected_bases", "selected_editable_objects",
+ "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
"active_base", "active_object", "visible_bones", "editable_bones",
- "selected_bones", "selected_editable_bones" "visible_pchans",
+ "selected_bones", "selected_editable_bones", "visible_pchans",
"selected_pchans", "active_bone", "active_pchan", NULL};
CTX_data_dir_set(result, dir);
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index ece304fb2b5..c50aa4fc2ed 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -153,8 +153,9 @@ typedef struct {
/* is used for both read and write... */
-static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, Object *ob, float lim)
+static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d, Object *ob, float lim)
{
+ uiBlock *block= (layout)? uiLayoutAbsoluteBlock(layout): NULL;
MDeformVert *dvert=NULL;
TransformProperties *tfp= v3d->properties_storage;
float median[5], ve_median[5];
@@ -474,6 +475,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d,
}
}
+#if 0
/* assumes armature active */
static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
{
@@ -492,14 +494,17 @@ static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
ED_armature_bone_rename(ob->data, oldname, newname); // editarmature.c
}
}
+#endif
-static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
+static void v3d_posearmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
{
- uiBut *but;
+ uiBlock *block= uiLayoutGetBlock(layout);
bArmature *arm;
bPoseChannel *pchan;
Bone *bone= NULL;
TransformProperties *tfp= v3d->properties_storage;
+ PointerRNA pchanptr;
+ uiLayout *row;
arm = ob->data;
if (!arm || !ob->pose) return;
@@ -509,14 +514,26 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float
if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
break;
}
+ if (!pchan) {
+ uiDefBut(block, LABEL, 0, "No Bone Active", 0, 240, 100, 20, 0, 0, 0, 0, 0, "");
+ return;
+ }
+ else {
+ row= uiLayoutRow(layout, 0);
+ RNA_pointer_create(&ob->id, &RNA_PoseChannel, pchan, &pchanptr);
+ uiItemL(row, "", ICON_BONE_DATA);
+ uiItemR(row, "", 0, &pchanptr, "name", 0);
+ }
- if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ uiLayoutAbsoluteBlock(layout);
+
+ if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float quat[4];
/* convert to euler, passing through quats... */
- AxisAngleToQuat(quat, &pchan->quat[1], pchan->quat[0]);
+ AxisAngleToQuat(quat, pchan->rotAxis, pchan->rotAngle);
QuatToEul(quat, tfp->ob_eul);
}
- else if (pchan->rotmode == PCHAN_ROT_QUAT)
+ else if (pchan->rotmode == ROT_MODE_QUAT)
QuatToEul(pchan->quat, tfp->ob_eul);
else
VecCopyf(tfp->ob_eul, pchan->eul);
@@ -580,12 +597,14 @@ void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev)
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix
}
-static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
+static void v3d_editarmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
{
+ uiBlock *block= uiLayoutGetBlock(layout);
bArmature *arm= ob->data;
EditBone *ebone;
- uiBut *but;
TransformProperties *tfp= v3d->properties_storage;
+ uiLayout *row;
+ PointerRNA eboneptr;
ebone= arm->edbo->first;
@@ -597,6 +616,13 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float
if (!ebone)
return;
+ row= uiLayoutRow(layout, 0);
+ RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &eboneptr);
+ uiItemL(row, "", ICON_BONE_DATA);
+ uiItemR(row, "", 0, &eboneptr, "name", 0);
+
+ uiLayoutAbsoluteBlock(layout);
+
uiDefBut(block, LABEL, 0, "Head:", 0, 210, 100, 20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_ARMATUREPANEL1, "X:", 0, 190, 100, 19, ebone->head, -lim, lim, 10, 3, "X Location of the head end of the bone");
@@ -624,8 +650,9 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float
}
-static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim)
+static void v3d_editmetaball_buts(uiLayout *layout, Object *ob, float lim)
{
+ uiBlock *block= uiLayoutAbsoluteBlock(layout);
MetaElem *lastelem= NULL; // XXX
if(lastelem) {
@@ -683,9 +710,24 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
case B_OBJECTPANELROT:
if(ob) {
- ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0;
- ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0;
- ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0;
+ float eul[3];
+
+ /* make a copy to eul[3], to allow TAB on buttons to work */
+ eul[0]= M_PI*tfp->ob_eul[0]/180.0;
+ eul[1]= M_PI*tfp->ob_eul[1]/180.0;
+ eul[2]= M_PI*tfp->ob_eul[2]/180.0;
+
+ if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ float quat[4];
+ /* convert to axis-angle, passing through quats */
+ EulToQuat(eul, quat);
+ QuatToAxisAngle(quat, ob->rotAxis, &ob->rotAngle);
+ }
+ else if (ob->rotmode == ROT_MODE_QUAT)
+ EulToQuat(eul, ob->quat);
+ else
+ VecCopyf(ob->rot, eul);
+
DAG_id_flush_update(&ob->id, OB_RECALC_OB);
}
break;
@@ -860,17 +902,16 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
eul[1]= M_PI*tfp->ob_eul[1]/180.0;
eul[2]= M_PI*tfp->ob_eul[2]/180.0;
- if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
+ if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float quat[4];
/* convert to axis-angle, passing through quats */
EulToQuat(eul, quat);
- QuatToAxisAngle(quat, &pchan->quat[1], &pchan->quat[0]);
+ QuatToAxisAngle(quat, pchan->rotAxis, &pchan->rotAngle);
}
- else if (pchan->rotmode == PCHAN_ROT_QUAT)
+ else if (pchan->rotmode == ROT_MODE_QUAT)
EulToQuat(eul, pchan->quat);
else
VecCopyf(pchan->eul, eul);
-
}
/* no break, pass on */
case B_ARMATUREPANEL2:
@@ -880,7 +921,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
}
break;
case B_TRANSFORMSPACEADD:
- BIF_manageTransformOrientation(C, 1, 0);
+ BIF_createTransformOrientation(C, NULL, "", 1, 0);
break;
case B_TRANSFORMSPACECLEAR:
BIF_clearTransformOrientation(C);
@@ -993,7 +1034,7 @@ static void view3d_panel_transform_spaces(const bContext *C, Panel *pa)
int xco = 20, yco = 70;
int index;
- block= uiLayoutFreeBlock(pa->layout);
+ block= uiLayoutAbsoluteBlock(pa->layout);
uiBlockBeginAlign(block);
@@ -1075,6 +1116,8 @@ static void view3d_panel_object(const bContext *C, Panel *pa)
//uiBut *bt;
Object *ob= OBACT;
TransformProperties *tfp;
+ PointerRNA obptr;
+ uiLayout *col, *row;
float lim;
if(ob==NULL) return;
@@ -1084,33 +1127,42 @@ static void view3d_panel_object(const bContext *C, Panel *pa)
v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
tfp= v3d->properties_storage;
- block= uiLayoutFreeBlock(pa->layout);
- uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
-
// XXX uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-
+ /*
if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) {
}
else {
if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) {
- strcpy(ob->parsubstr, "");
uiBlockEndAlign(block);
}
}
+ */
lim= 10000.0f*MAX2(1.0, v3d->grid);
+ block= uiLayoutGetBlock(pa->layout);
+ uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
+
+ col= uiLayoutColumn(pa->layout, 0);
+ row= uiLayoutRow(col, 0);
+ RNA_id_pointer_create(&ob->id, &obptr);
+ uiItemL(row, "", ICON_OBJECT_DATA);
+ uiItemR(row, "", 0, &obptr, "name", 0);
+
if(ob==obedit) {
- if(ob->type==OB_ARMATURE) v3d_editarmature_buts(block, v3d, ob, lim);
- if(ob->type==OB_MBALL) v3d_editmetaball_buts(block, ob, lim);
- else v3d_editvertex_buts(C, block, v3d, ob, lim);
+ if(ob->type==OB_ARMATURE) v3d_editarmature_buts(col, v3d, ob, lim);
+ if(ob->type==OB_MBALL) v3d_editmetaball_buts(col, ob, lim);
+ else v3d_editvertex_buts(C, col, v3d, ob, lim);
}
else if(ob->mode & OB_MODE_POSE) {
- v3d_posearmature_buts(block, v3d, ob, lim);
+ v3d_posearmature_buts(col, v3d, ob, lim);
}
else {
BoundBox *bb = NULL;
-
+
+ uiLayoutAbsoluteBlock(col);
+
+ block= uiLayoutAbsoluteBlock(col);
uiDefBut(block, LABEL, 0, "Location:", 0, 300, 100, 20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_OBJECTPANEL, "X:", 0, 280, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
@@ -1124,9 +1176,19 @@ static void view3d_panel_object(const bContext *C, Panel *pa)
uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 125, 240, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Location value from being Transformed");
uiBlockEndAlign(block);
- tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI;
- tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI;
- tfp->ob_eul[2]= 180.0*ob->rot[2]/M_PI;
+ if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ float quat[4];
+ /* convert to euler, passing through quats... */
+ AxisAngleToQuat(quat, ob->rotAxis, ob->rotAngle);
+ QuatToEul(quat, tfp->ob_eul);
+ }
+ else if (ob->rotmode == ROT_MODE_QUAT)
+ QuatToEul(ob->quat, tfp->ob_eul);
+ else
+ VecCopyf(tfp->ob_eul, ob->rot);
+ tfp->ob_eul[0]*= 180.0/M_PI;
+ tfp->ob_eul[1]*= 180.0/M_PI;
+ tfp->ob_eul[2]*= 180.0/M_PI;
uiBlockBeginAlign(block);
if ((ob->parent) && (ob->partype == PARBONE)) {
@@ -1277,7 +1339,7 @@ static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
};
- block= uiLayoutFreeBlock(pa->layout);
+ block= uiLayoutAbsoluteBlock(pa->layout);
uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
uiBlockBeginAlign(block);
@@ -1445,25 +1507,12 @@ void view3d_buttons_register(ARegionType *art)
pt->draw= view3d_panel_transform_spaces;
BLI_addtail(&art->paneltypes, pt);
- pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
- strcpy(pt->idname, "VIEW3D_PT_gpencil");
- strcpy(pt->label, "Greas Pencil");
- pt->draw= view3d_panel_gpencil;
- BLI_addtail(&art->paneltypes, pt);*/
-
pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel bonesketch spaces");
strcpy(pt->idname, "VIEW3D_PT_bonesketch_spaces");
strcpy(pt->label, "Bone Sketching");
pt->draw= view3d_panel_bonesketch_spaces;
pt->poll= view3d_panel_bonesketch_spaces_poll;
BLI_addtail(&art->paneltypes, pt);
-
- /*
- pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel redo");
- strcpy(pt->idname, "VIEW3D_PT_redo");
- strcpy(pt->label, "Last Operator");
- pt->draw= view3d_panel_operator_redo;
- BLI_addtail(&art->paneltypes, pt);
*/
// XXX view3d_panel_preview(C, ar, 0);
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index f8584b14e2b..fac3f9fb555 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -732,7 +732,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d)
char *name = view3d_get_name(v3d, rv3d);
char *printable = NULL;
- if (v3d->localview) {
+ if (v3d->localvd) {
printable = malloc(strlen(name) + strlen(" (Local)_")); /* '_' gives space for '\0' */
strcpy(printable, name);
strcat(printable, " (Local)");
@@ -745,7 +745,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d)
BLF_draw_default(22, ar->winy-17, 0.0f, printable);
}
- if (v3d->localview) {
+ if (v3d->localvd) {
free(printable);
}
}
@@ -1413,6 +1413,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
}
if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ glDepthMask(0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -1433,6 +1434,8 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
wmPopMatrix();
glDisable(GL_BLEND);
+
+ glDepthMask(1);
if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
@@ -1961,6 +1964,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
v3d->zbuf= TRUE;
glEnable(GL_DEPTH_TEST);
}
+ else
+ v3d->zbuf= FALSE;
// needs to be done always, gridview is adjusted in drawgrid() now
v3d->gridview= v3d->grid;
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index bbcee0415f8..cee5c82ef38 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -239,9 +239,10 @@ typedef struct ViewOpsData {
float ofs[3], obofs[3];
float reverse, dist0;
float grid, far;
+ short axis_snap; /* view rotate only */
int origx, origy, oldx, oldy;
- int origkey;
+ int origkey; /* the key that triggered the operator */
} ViewOpsData;
@@ -276,6 +277,7 @@ static void calctrackballvec(rcti *rect, int mx, int my, float *vec)
static void viewops_data(bContext *C, wmOperator *op, wmEvent *event)
{
+ static float lastofs[3] = {0,0,0};
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d;
ViewOpsData *vod= MEM_callocN(sizeof(ViewOpsData), "viewops data");
@@ -289,7 +291,16 @@ static void viewops_data(bContext *C, wmOperator *op, wmEvent *event)
QUATCOPY(vod->oldquat, rv3d->viewquat);
vod->origx= vod->oldx= event->x;
vod->origy= vod->oldy= event->y;
- vod->origkey= event->type;
+ vod->origkey= event->type; /* the key that triggered the operator. */
+
+ if (U.uiflag & USER_ORBIT_SELECTION)
+ {
+ VECCOPY(vod->ofs, rv3d->ofs);
+ /* If there's no selection, lastofs is unmodified and last value since static */
+ calculateTransformCenter(C, event, V3D_CENTROID, lastofs);
+ VECCOPY(vod->obofs, lastofs);
+ VecMulf(vod->obofs, -1.0f);
+ }
/* lookup, we dont pass on v3d to prevent confusement */
vod->grid= v3d->grid;
@@ -357,11 +368,52 @@ static float snapquats[39][6] = {
{0.0, 0.0, 0.0, 1.0, 0, 0}
};
+enum {
+ VIEW_PASS= 0,
+ VIEW_APPLY,
+ VIEW_CONFIRM
+};
+
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+#define VIEW_MODAL_CONFIRM 1 /* used for all view operations */
+#define VIEWROT_MODAL_AXIS_SNAP_ENABLE 2
+#define VIEWROT_MODAL_AXIS_SNAP_DISABLE 3
+
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+void viewrotate_modal_keymap(wmKeyConfig *keyconf)
+{
+ static EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Cancel", ""},
+
+ {VIEWROT_MODAL_AXIS_SNAP_ENABLE, "AXIS_SNAP_ENABLE", 0, "Enable Axis Snap", ""},
+ {VIEWROT_MODAL_AXIS_SNAP_DISABLE, "AXIS_SNAP_DISABLE", 0, "Enable Axis Snap", ""},
+
+ {0, NULL, 0, NULL, NULL}};
+
+ wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Rotate Modal");
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if(keymap) return;
+
+ keymap= WM_modalkeymap_add(keyconf, "View3D Rotate Modal", modal_items);
-static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl)
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_ENABLE);
+ WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_DISABLE);
+
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate");
+
+}
+
+static void viewrotate_apply(ViewOpsData *vod, int x, int y)
{
RegionView3D *rv3d= vod->rv3d;
- int use_sel= 0; /* XXX */
+ int use_sel= U.uiflag & USER_ORBIT_SELECTION;
rv3d->view= 0; /* need to reset everytime because of view snapping */
@@ -462,7 +514,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl)
}
/* check for view snap */
- if (ctrl){
+ if (vod->axis_snap){
int i;
float viewmat[3][3];
@@ -496,23 +548,41 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl)
static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event)
{
ViewOpsData *vod= op->customdata;
+ short event_code= VIEW_PASS;
/* execute the events */
- switch(event->type) {
- case MOUSEMOVE:
- viewrotate_apply(vod, event->x, event->y, event->ctrl);
- break;
+ if(event->type==MOUSEMOVE) {
+ event_code= VIEW_APPLY;
+ }
+ else if(event->type==EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code= VIEW_CONFIRM;
+ break;
+ case VIEWROT_MODAL_AXIS_SNAP_ENABLE:
+ vod->axis_snap= TRUE;
+ event_code= VIEW_APPLY;
+ break;
+ case VIEWROT_MODAL_AXIS_SNAP_DISABLE:
+ vod->axis_snap= FALSE;
+ event_code= VIEW_APPLY;
+ break;
+ }
+ }
+ else if(event->type==vod->origkey && event->val==KM_RELEASE) {
+ event_code= VIEW_CONFIRM;
+ }
- default:
- /* origkey may be zero when invoked from a button */
- if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) {
- request_depth_update(CTX_wm_region_view3d(C));
+ if(event_code==VIEW_APPLY) {
+ viewrotate_apply(vod, event->x, event->y);
+ }
+ else if (event_code==VIEW_CONFIRM) {
+ request_depth_update(CTX_wm_region_view3d(C));
- MEM_freeN(vod);
- op->customdata= NULL;
+ MEM_freeN(vod);
+ op->customdata= NULL;
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
return OPERATOR_RUNNING_MODAL;
@@ -541,19 +611,19 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
-void VIEW3D_OT_viewrotate(wmOperatorType *ot)
+void VIEW3D_OT_rotate(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Rotate view";
ot->description = "Rotate the view.";
- ot->idname= "VIEW3D_OT_viewrotate";
+ ot->idname= "VIEW3D_OT_rotate";
/* api callbacks */
ot->invoke= viewrotate_invoke;
@@ -561,11 +631,38 @@ void VIEW3D_OT_viewrotate(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
}
/* ************************ viewmove ******************************** */
+
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+void viewmove_modal_keymap(wmKeyConfig *keyconf)
+{
+ static EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+
+ {0, NULL, 0, NULL, NULL}};
+
+ wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Move Modal");
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if(keymap) return;
+
+ keymap= WM_modalkeymap_add(keyconf, "View3D Move Modal", modal_items);
+
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_move");
+}
+
+
static void viewmove_apply(ViewOpsData *vod, int x, int y)
{
if(vod->rv3d->persp==V3D_CAMOB) {
@@ -596,24 +693,35 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
{
+
ViewOpsData *vod= op->customdata;
+ short event_code= VIEW_PASS;
/* execute the events */
- switch(event->type) {
- case MOUSEMOVE:
- viewmove_apply(vod, event->x, event->y);
- break;
+ if(event->type==MOUSEMOVE) {
+ event_code= VIEW_APPLY;
+ }
+ else if(event->type==EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code= VIEW_CONFIRM;
+ break;
+ }
+ }
+ else if(event->type==vod->origkey && event->val==KM_RELEASE) {
+ event_code= VIEW_CONFIRM;
+ }
- default:
- /* origkey may be zero when invoked from a button */
- if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) {
- request_depth_update(CTX_wm_region_view3d(C));
+ if(event_code==VIEW_APPLY) {
+ viewmove_apply(vod, event->x, event->y);
+ }
+ else if (event_code==VIEW_CONFIRM) {
+ request_depth_update(CTX_wm_region_view3d(C));
- MEM_freeN(vod);
- op->customdata= NULL;
+ MEM_freeN(vod);
+ op->customdata= NULL;
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
return OPERATOR_RUNNING_MODAL;
@@ -625,19 +733,19 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
viewops_data(C, op, event);
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
-void VIEW3D_OT_viewmove(wmOperatorType *ot)
+void VIEW3D_OT_move(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Move view";
ot->description = "Move the view.";
- ot->idname= "VIEW3D_OT_viewmove";
+ ot->idname= "VIEW3D_OT_move";
/* api callbacks */
ot->invoke= viewmove_invoke;
@@ -645,11 +753,34 @@ void VIEW3D_OT_viewmove(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
}
/* ************************ viewzoom ******************************** */
+/* called in transform_ops.c, on each regeneration of keymaps */
+void viewzoom_modal_keymap(wmKeyConfig *keyconf)
+{
+ static EnumPropertyItem modal_items[] = {
+ {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+
+ {0, NULL, 0, NULL, NULL}};
+
+ wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Zoom Modal");
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if(keymap) return;
+
+ keymap= WM_modalkeymap_add(keyconf, "View3D Zoom Modal", modal_items);
+
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
+
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom");
+}
+
static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
{
RegionView3D *rv3d= ar->regiondata;
@@ -758,23 +889,33 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y)
static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event)
{
ViewOpsData *vod= op->customdata;
+ short event_code= VIEW_PASS;
/* execute the events */
- switch(event->type) {
- case MOUSEMOVE:
- viewzoom_apply(vod, event->x, event->y);
- break;
+ if(event->type==MOUSEMOVE) {
+ event_code= VIEW_APPLY;
+ }
+ else if(event->type==EVT_MODAL_MAP) {
+ switch (event->val) {
+ case VIEW_MODAL_CONFIRM:
+ event_code= VIEW_CONFIRM;
+ break;
+ }
+ }
+ else if(event->type==vod->origkey && event->val==KM_RELEASE) {
+ event_code= VIEW_CONFIRM;
+ }
- default:
- /* origkey may be zero when invoked from a button */
- if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) {
- request_depth_update(CTX_wm_region_view3d(C));
+ if(event_code==VIEW_APPLY) {
+ viewzoom_apply(vod, event->x, event->y);
+ }
+ else if (event_code==VIEW_CONFIRM) {
+ request_depth_update(CTX_wm_region_view3d(C));
- MEM_freeN(vod);
- op->customdata= NULL;
+ MEM_freeN(vod);
+ op->customdata= NULL;
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
return OPERATOR_RUNNING_MODAL;
@@ -823,7 +964,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
viewops_data(C, op, event);
/* add temp handler */
- WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -845,7 +986,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
}
@@ -925,7 +1066,7 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.
void VIEW3D_OT_view_all(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "View home";
+ ot->name= "View All";
ot->description = "View all objects in scene.";
ot->idname= "VIEW3D_OT_view_all";
@@ -1064,7 +1205,7 @@ void VIEW3D_OT_view_center(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "View center";
+ ot->name= "View Selected";
ot->description = "Move the view to the selection center.";
ot->idname= "VIEW3D_OT_view_center";
@@ -1628,7 +1769,7 @@ static int viewpersportho_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_view_persportho(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "View persp/ortho";
+ ot->name= "View Persp/Ortho";
ot->description = "Switch the current view from perspective/orthographic.";
ot->idname= "VIEW3D_OT_view_persportho";
@@ -1748,57 +1889,6 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
}
-/* ********************* draw type operator ****************** */
-
-static int view3d_drawtype_exec(bContext *C, wmOperator *op)
-{
- View3D *v3d = CTX_wm_view3d(C);
- int dt, dt_alt;
-
- dt = RNA_int_get(op->ptr, "draw_type");
- dt_alt = RNA_int_get(op->ptr, "draw_type_alternate");
-
- if (dt_alt != -1) {
- if (v3d->drawtype == dt)
- v3d->drawtype = dt_alt;
- else
- v3d->drawtype = dt;
- }
- else
- v3d->drawtype = dt;
-
- ED_area_tag_redraw(CTX_wm_area(C));
-
- return OPERATOR_FINISHED;
-}
-
-static int view3d_drawtype_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- return view3d_drawtype_exec(C, op);
-}
-
-/* toggles */
-void VIEW3D_OT_drawtype(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Change draw type";
- ot->description = "Change the draw type of the view.";
- ot->idname= "VIEW3D_OT_drawtype";
-
- /* api callbacks */
- ot->invoke= view3d_drawtype_invoke;
- ot->exec= view3d_drawtype_exec;
-
- ot->poll= ED_operator_view3d_active;
-
- /* flags */
- ot->flag= 0;
-
- /* rna XXX should become enum */
- RNA_def_int(ot->srna, "draw_type", 0, INT_MIN, INT_MAX, "Draw Type", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "draw_type_alternate", -1, INT_MIN, INT_MAX, "Draw Type Alternate", "", INT_MIN, INT_MAX);
-}
-
/* ***************** 3d cursor cursor op ******************* */
/* mx my in region coords */
@@ -1850,8 +1940,7 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
// XXX notifier for scene */
ED_area_tag_redraw(CTX_wm_area(C));
- /* prevent other mouse ops to fail */
- return OPERATOR_PASS_THROUGH;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_cursor3d(wmOperatorType *ot)
@@ -2339,7 +2428,7 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
if (use_sel) {
QuatConj(q1); /* conj == inv for unit quat */
- VecSubf(v3d->ofs, v3d->ofs, obofs);
+ VecSubf(rv3d->ofs, rv3d->ofs, obofs);
QuatMulVecf(q1, rv3d->ofs);
VecAddf(rv3d->ofs, rv3d->ofs, obofs);
}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 0c1d0ba28d2..95900e6faa3 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -178,7 +178,7 @@ static void handle_view3d_lock(bContext *C)
View3D *v3d= CTX_wm_view3d(C);
if (v3d != NULL && sa != NULL) {
- if(v3d->localview==0 && v3d->scenelock && sa->spacetype==SPACE_VIEW3D) {
+ if(v3d->localvd==NULL && v3d->scenelock && sa->spacetype==SPACE_VIEW3D) {
/* copy to scene */
scene->lay= v3d->lay;
@@ -196,27 +196,38 @@ static int layers_exec(bContext *C, wmOperator *op)
View3D *v3d= sa->spacedata.first;
int nr= RNA_int_get(op->ptr, "nr");
- if(nr<=0)
+ if(nr < 0)
return OPERATOR_CANCELLED;
- nr--;
-
- if(RNA_boolean_get(op->ptr, "extend"))
- v3d->lay |= (1<<nr);
- else
- v3d->lay = (1<<nr);
-
- /* set active layer, ensure to always have one */
- if(v3d->lay & (1<<nr))
- v3d->layact= 1<<nr;
- else if((v3d->lay & v3d->layact)==0) {
- int bit= 0;
+
+
+ if(nr == 0) {
+ /* all layers */
+ v3d->lay |= (1<<20)-1;
+
+ if(!v3d->layact)
+ v3d->layact= 1;
+ }
+ else {
+ nr--;
+
+ if(RNA_boolean_get(op->ptr, "extend"))
+ v3d->lay |= (1<<nr);
+ else
+ v3d->lay = (1<<nr);
- while(bit<32) {
- if(v3d->lay & (1<<bit)) {
- v3d->layact= 1<<bit;
- break;
+ /* set active layer, ensure to always have one */
+ if(v3d->lay & (1<<nr))
+ v3d->layact= 1<<nr;
+ else if((v3d->lay & v3d->layact)==0) {
+ int bit= 0;
+
+ while(bit<32) {
+ if(v3d->lay & (1<<bit)) {
+ v3d->layact= 1<<bit;
+ break;
+ }
+ bit++;
}
- bit++;
}
}
@@ -264,8 +275,8 @@ void VIEW3D_OT_layers(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "", 0, 20);
- RNA_def_boolean(ot->srna, "extend", 0, "Extend", "");
+ RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "The layer number to set, zero for all layers", 0, 20);
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Add this layer to the current view layers");
}
#if 0
@@ -1802,8 +1813,10 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
ED_area_tag_redraw(sa);
break;
case B_NDOF:
+ ED_area_tag_redraw(sa);
break;
case B_MAN_MODE:
+ ED_area_tag_redraw(sa);
break;
case B_VIEW_BUTSEDIT:
break;
@@ -1949,7 +1962,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
uiBlock *block;
int a, xco=0, maxco=0, yco= 0;
- block= uiLayoutFreeBlock(layout);
+ block= uiLayoutAbsoluteBlock(layout);
uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL);
if((sa->flag & HEADER_NO_PULLDOWN)==0)
@@ -2074,7 +2087,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
}
/* LAYERS */
- if(obedit==NULL && v3d->localview==0) {
+ if(obedit==NULL && v3d->localvd==NULL) {
int ob_lay = ob ? ob->lay : 0;
uiBlockBeginAlign(block);
for(a=0; a<5; a++) {
@@ -2113,7 +2126,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
xco+= XIC+10;
}
uiBlockEndAlign(block);
- header_xco_step(ar, &xco, &yco, &maxco, XIC+10);
+ header_xco_step(ar, &xco, &yco, &maxco, 10);
}
/* Snap */
@@ -2129,10 +2142,14 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, ICON_SNAP_PEEL_OBJECT,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center");
xco+= XIC;
}
+ if (ts->snap_mode == SCE_SNAP_MODE_FACE) {
+ uiDefIconButBitS(block, TOG, SCE_SNAP_PROJECT, B_REDR, ICON_RETOPO,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Project elements instead of snapping them");
+ xco+= XIC;
+ }
uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode");
- xco+= XIC;
+ xco+= XIC + 10;
uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &ts->snap_target, 0, 0, 0, 0, "Snap Target Mode");
- xco+= XIC+70;
+ xco+= 70;
} else {
uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");
xco+= XIC;
@@ -2154,10 +2171,11 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, xco,yco,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Face select mode (Ctrl Tab 3)");
xco+= XIC;
uiBlockEndAlign(block);
+ header_xco_step(ar, &xco, &yco, &maxco, 10);
if(v3d->drawtype > OB_WIRE) {
uiDefIconButBitS(block, TOG, V3D_ZBUF_SELECT, B_REDR, ICON_ORTHO, xco,yco,XIC,YIC, &v3d->flag, 1.0, 0.0, 0, 0, "Occlude background geometry");
- xco+= XIC;
}
+ xco+= XIC;
uiBlockEndAlign(block);
header_xco_step(ar, &xco, &yco, &maxco, XIC);
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 7dbea44b68b..84d1a1275a9 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -62,12 +62,12 @@ void VIEW3D_OT_layers(struct wmOperatorType *ot);
/* view3d_ops.c */
void view3d_operatortypes(void);
-void view3d_keymap(struct wmWindowManager *wm);
+void view3d_keymap(struct wmKeyConfig *keyconf);
/* view3d_edit.c */
void VIEW3D_OT_zoom(struct wmOperatorType *ot);
-void VIEW3D_OT_viewmove(struct wmOperatorType *ot);
-void VIEW3D_OT_viewrotate(struct wmOperatorType *ot);
+void VIEW3D_OT_move(struct wmOperatorType *ot);
+void VIEW3D_OT_rotate(struct wmOperatorType *ot);
void VIEW3D_OT_view_all(struct wmOperatorType *ot);
void VIEW3D_OT_viewnumpad(struct wmOperatorType *ot);
void VIEW3D_OT_view_center(struct wmOperatorType *ot);
@@ -89,10 +89,13 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int dt, int outline);
void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob);
void drawaxes(float size, int flag, char drawtype);
-void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs);
+
+void view3d_cached_text_draw_begin(void);
+void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs);
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]);
/* drawarmature.c */
-int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag);
+int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag);
/* drawmesh.c */
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, struct DerivedMesh *dm, int faceselect);
@@ -119,8 +122,10 @@ void VIEW3D_OT_select_lasso(struct wmOperatorType *ot);
/* view3d_view.c */
void VIEW3D_OT_smoothview(struct wmOperatorType *ot);
void VIEW3D_OT_setcameratoview(struct wmOperatorType *ot);
+void VIEW3D_OT_setobjectascamera(struct wmOperatorType *ot);
void VIEW3D_OT_localview(struct wmOperatorType *ot);
void VIEW3D_OT_game_start(struct wmOperatorType *ot);
+void VIEW3D_OT_fly(struct wmOperatorType *ot);
int boundbox_clip(RegionView3D *rv3d, float obmat[][4], struct BoundBox *bb);
@@ -132,6 +137,11 @@ void smooth_view(struct bContext *C, Object *, Object *, float *ofs, float *quat
void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); /* rect: for picking */
void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d);
+void fly_modal_keymap(struct wmKeyConfig *keyconf);
+void viewrotate_modal_keymap(struct wmKeyConfig *keyconf);
+void viewmove_modal_keymap(struct wmKeyConfig *keyconf);
+void viewzoom_modal_keymap(struct wmKeyConfig *keyconf);
+
/* view3d_buttons.c */
void VIEW3D_OT_properties(struct wmOperatorType *ot);
void view3d_buttons_register(struct ARegionType *art);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index e179809adc9..4b692e572e2 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -62,8 +62,8 @@
void view3d_operatortypes(void)
{
- WM_operatortype_append(VIEW3D_OT_viewrotate);
- WM_operatortype_append(VIEW3D_OT_viewmove);
+ WM_operatortype_append(VIEW3D_OT_rotate);
+ WM_operatortype_append(VIEW3D_OT_move);
WM_operatortype_append(VIEW3D_OT_zoom);
WM_operatortype_append(VIEW3D_OT_view_all);
WM_operatortype_append(VIEW3D_OT_viewnumpad);
@@ -82,9 +82,10 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_cursor3d);
WM_operatortype_append(VIEW3D_OT_select_lasso);
WM_operatortype_append(VIEW3D_OT_setcameratoview);
- WM_operatortype_append(VIEW3D_OT_drawtype);
+ WM_operatortype_append(VIEW3D_OT_setobjectascamera);
WM_operatortype_append(VIEW3D_OT_localview);
WM_operatortype_append(VIEW3D_OT_game_start);
+ WM_operatortype_append(VIEW3D_OT_fly);
WM_operatortype_append(VIEW3D_OT_layers);
WM_operatortype_append(VIEW3D_OT_properties);
@@ -101,46 +102,30 @@ void view3d_operatortypes(void)
transform_operatortypes();
}
-void view3d_keymap(wmWindowManager *wm)
+void view3d_keymap(wmKeyConfig *keyconf)
{
- ListBase *keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0);
- wmKeymapItem *km;
+ wmKeyMap *keymap;
+ wmKeyMapItem *km;
+
+ keymap= WM_keymap_find(keyconf, "View3D Generic", SPACE_VIEW3D, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_toolbar", TKEY, KM_PRESS, 0, 0);
/* only for region 3D window */
- keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0);
-
- /* paint poll checks mode */
- WM_keymap_verify_item(keymap, "PAINT_OT_vertex_paint", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "PAINT_OT_weight_paint", LEFTMOUSE, KM_PRESS, 0, 0);
-
- WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
-
- WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
-
- /* sketch poll checks mode */
- WM_keymap_add_item(keymap, "SKETCH_OT_gesture", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, 0, 0);
- km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
- RNA_boolean_set(km->ptr, "snap", 1);
- WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0);
- km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0);
- RNA_boolean_set(km->ptr, "snap", 1);
+ keymap= WM_keymap_find(keyconf, "View3D", SPACE_VIEW3D, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, 0, 0); /* manipulator always on left mouse, not on action mouse*/
WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "VIEW3D_OT_viewrotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "VIEW3D_OT_viewmove", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center", PADPERIOD, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "VIEW3D_OT_fly", FKEY, KM_PRESS, KM_SHIFT, 0);
+
WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
@@ -175,6 +160,7 @@ void view3d_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0);
/* layers, shift + alt are properties set in invoke() */
+ RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ACCENTGRAVEKEY, KM_PRESS, 0, 0)->ptr, "nr", 0);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ONEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 1);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", TWOKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 2);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", THREEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 3);
@@ -187,17 +173,21 @@ void view3d_keymap(wmWindowManager *wm)
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ZEROKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 10);
/* drawtype */
- km = WM_keymap_add_item(keymap, "VIEW3D_OT_drawtype", ZKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "draw_type", OB_SOLID);
- RNA_int_set(km->ptr, "draw_type_alternate", OB_WIRE);
- km = WM_keymap_add_item(keymap, "VIEW3D_OT_drawtype", ZKEY, KM_PRESS, KM_ALT, 0);
- RNA_int_set(km->ptr, "draw_type", OB_TEXTURE);
- RNA_int_set(km->ptr, "draw_type_alternate", OB_SOLID);
+ km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, 0, 0);
+ RNA_string_set(km->ptr, "path", "space_data.viewport_shading");
+ RNA_string_set(km->ptr, "value_1", "SOLID");
+ RNA_string_set(km->ptr, "value_2", "WIREFRAME");
+
+ km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, KM_ALT, 0);
+ RNA_string_set(km->ptr, "path", "space_data.viewport_shading");
+ RNA_string_set(km->ptr, "value_1", "TEXTURED");
+ RNA_string_set(km->ptr, "value_2", "SOLID");
- km = WM_keymap_add_item(keymap, "VIEW3D_OT_drawtype", ZKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_int_set(km->ptr, "draw_type", OB_SHADED);
- RNA_int_set(km->ptr, "draw_type_alternate", OB_WIRE);
+ km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(km->ptr, "path", "space_data.viewport_shading");
+ RNA_string_set(km->ptr, "value_1", "SHADED");
+ RNA_string_set(km->ptr, "value_2", "WIREFRAME");
/* selection*/
WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
@@ -230,22 +220,40 @@ void view3d_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT|KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_object_as_camera", PAD0, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0);
-
- /* radial control */
- RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
- RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
- RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
- RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
+ /* context ops */
+ km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0);
+ RNA_string_set(km->ptr, "path", "space_data.pivot_point");
+ RNA_string_set(km->ptr, "value", "BOUNDING_BOX_CENTER");
+
+ km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, KM_CTRL, 0); /* 2.4x allowed Comma+Shift too, rather not use both */
+ RNA_string_set(km->ptr, "path", "space_data.pivot_point");
+ RNA_string_set(km->ptr, "value", "MEDIAN_POINT");
+
+ km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", COMMAKEY, KM_PRESS, KM_ALT, 0); /* new in 2.5 */
+ RNA_string_set(km->ptr, "path", "space_data.pivot_point_align");
+
+ km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, 0, 0);
+ RNA_string_set(km->ptr, "path", "space_data.pivot_point");
+ RNA_string_set(km->ptr, "value", "CURSOR");
+
+ km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(km->ptr, "path", "space_data.pivot_point");
+ RNA_string_set(km->ptr, "value", "INDIVIDUAL_CENTERS");
+
+ km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_ALT, 0);
+ RNA_string_set(km->ptr, "path", "space_data.pivot_point");
+ RNA_string_set(km->ptr, "value", "ACTIVE_ELEMENT");
+
- transform_keymap_for_space(wm, keymap, SPACE_VIEW3D);
+ transform_keymap_for_space(keyconf, keymap, SPACE_VIEW3D);
+ fly_modal_keymap(keyconf);
+ viewrotate_modal_keymap(keyconf);
+ viewmove_modal_keymap(keyconf);
+ viewzoom_modal_keymap(keyconf);
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 4563b21d6c1..eb85c4ff722 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -465,7 +465,10 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves
data.pass = 0;
bbsel= EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+
if(vc->scene->toolsettings->selectmode & SCE_SELECT_VERTEX) {
if (bbsel) {
EM_backbuf_checkAndSelectVerts(vc->em, select);
@@ -590,6 +593,7 @@ static void do_lasso_select_curve(ViewContext *vc, short mcords[][2], short move
data.moves = moves;
data.select = select;
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data);
}
@@ -610,6 +614,7 @@ static void do_lasso_select_lattice(ViewContext *vc, short mcords[][2], short mo
data.moves = moves;
data.select = select;
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data);
}
@@ -1160,7 +1165,7 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter,
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, basact->object);
/* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
- if(basact->object->mode & OB_MODE_WEIGHT_PAINT) {
+ if(BASACT && BASACT->object->mode & OB_MODE_WEIGHT_PAINT) {
/* prevent activating */
basact= NULL;
}
@@ -1268,6 +1273,7 @@ static void do_nurbs_box_select(ViewContext *vc, rcti *rect, int select)
data.rect = rect;
data.select = select;
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data);
}
@@ -1287,6 +1293,7 @@ static void do_lattice_box_select(ViewContext *vc, rcti *rect, int select)
data.rect = rect;
data.select = select;
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data);
}
@@ -1340,6 +1347,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select)
data.done = 0;
bbsel= EDBM_init_backbuf_border(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
if(vc->scene->toolsettings->selectmode & SCE_SELECT_VERTEX) {
if (bbsel) {
@@ -1725,6 +1733,7 @@ static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, floa
bbsel= EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0));
vc->em= ((Mesh *)vc->obedit->data)->edit_btmesh;
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
data.select = selecting;
data.mval[0] = mval[0];
@@ -1793,6 +1802,7 @@ static void nurbscurve_circle_select(ViewContext *vc, int selecting, short *mval
data.mval[1] = mval[1];
data.radius = rad;
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data);
}
@@ -1818,6 +1828,7 @@ static void lattice_circle_select(ViewContext *vc, int selecting, short *mval, f
data.mval[1] = mval[1];
data.radius = rad;
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data);
}
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index 46341f53c26..e1c6f70bde0 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -163,7 +163,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
if(op==NULL)
return;
- if(op->type->poll && op->type->poll((bContext *)C)==0)
+ if(WM_operator_poll((bContext*)C, op->type) == 0)
return;
block= uiLayoutGetBlock(pa->layout);
@@ -208,7 +208,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u
for(; ot; ot= ot->next) {
if(BLI_strcasestr(ot->name, str)) {
- if(ot->poll==NULL || ot->poll((bContext *)C)) {
+ if(WM_operator_poll((bContext*)C, ot)) {
if(0==uiSearchItemAdd(items, ot->name, ot, 0))
break;
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index b6260e66af4..8aafe24e702 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -56,9 +56,11 @@
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
+#include "BKE_depsgraph.h" /* for fly mode updating */
#include "RE_pipeline.h" // make_stars
@@ -110,7 +112,7 @@ void view3d_operator_needs_opengl(const bContext *C)
float *give_cursor(Scene *scene, View3D *v3d)
{
- if(v3d && v3d->localview) return v3d->cursor;
+ if(v3d && v3d->localvd) return v3d->cursor;
else return scene->cursor;
}
@@ -384,26 +386,32 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
}
-static int view3d_setcameratoview_exec(bContext *C, wmOperator *op)
+static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob)
{
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d= CTX_wm_region_view3d(C);
- Object *ob;
float dvec[3];
- ob= v3d->camera;
dvec[0]= rv3d->dist*rv3d->viewinv[2][0];
dvec[1]= rv3d->dist*rv3d->viewinv[2][1];
dvec[2]= rv3d->dist*rv3d->viewinv[2][2];
VECCOPY(ob->loc, dvec);
- VecSubf(ob->loc, ob->loc, v3d->ofs);
+ VecSubf(ob->loc, ob->loc, rv3d->ofs);
rv3d->viewquat[0]= -rv3d->viewquat[0];
QuatToEul(rv3d->viewquat, ob->rot);
rv3d->viewquat[0]= -rv3d->viewquat[0];
ob->recalc= OB_RECALC_OB;
+}
+
+
+static int view3d_setcameratoview_exec(bContext *C, wmOperator *op)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d= CTX_wm_region_view3d(C);
+
+ setcameratoview3d(v3d, rv3d, v3d->camera);
+ rv3d->persp = V3D_CAMOB;
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, CTX_data_scene(C));
@@ -411,6 +419,16 @@ static int view3d_setcameratoview_exec(bContext *C, wmOperator *op)
}
+int view3d_setcameratoview_poll(bContext *C)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d= CTX_wm_region_view3d(C);
+
+ if (v3d==NULL || v3d->camera==NULL) return 0;
+ if (rv3d && rv3d->viewlock != 0) return 0;
+ return 1;
+}
+
void VIEW3D_OT_setcameratoview(wmOperatorType *ot)
{
@@ -421,16 +439,50 @@ void VIEW3D_OT_setcameratoview(wmOperatorType *ot)
/* api callbacks */
ot->exec= view3d_setcameratoview_exec;
- ot->poll= ED_operator_view3d_active;
+ ot->poll= view3d_setcameratoview_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d= CTX_wm_region_view3d(C);
+ Scene *scene= CTX_data_scene(C);
+
+ if(BASACT) {
+ rv3d->persp= V3D_CAMOB;
+ v3d->camera= OBACT;
+ if(v3d->scenelock)
+ scene->camera= OBACT;
+ smooth_view(C, NULL, v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens);
+ }
+
+ WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, CTX_data_scene(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void VIEW3D_OT_setobjectascamera(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name= "Set Active Object as Camera";
+ ot->description= "Set the active object as the active camera for this view or scene.";
+ ot->idname= "VIEW3D_OT_object_as_camera";
+
+ /* api callbacks */
+ ot->exec= view3d_setobjectascamera_exec;
+ ot->poll= ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
/* ********************************** */
/* create intersection coordinates in view Z direction at mouse coordinates */
-void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3])
+void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_end[3])
{
RegionView3D *rv3d= ar->regiondata;
float vec[4];
@@ -465,7 +517,7 @@ void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float
}
/* create intersection ray in view Z direction at mouse coordinates */
-void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3])
+void viewray(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_normal[3])
{
float ray_end[3];
@@ -1303,7 +1355,6 @@ static void initlocalview(Scene *scene, ScrArea *sa)
base->object->lay= base->lay;
}
}
- v3d->localview= 0;
}
}
@@ -1325,7 +1376,6 @@ static void restore_localviewdata(ScrArea *sa, int free)
if(free) {
MEM_freeN(v3d->localvd);
v3d->localvd= NULL;
- v3d->localview= 0;
}
for(ar= sa->regionbase.first; ar; ar= ar->next) {
@@ -1416,8 +1466,6 @@ static void SaveState(bContext *C)
glPushAttrib(GL_ALL_ATTRIB_BITS);
- GPU_state_init();
-
if(obact && obact->mode & OB_MODE_TEXTURE_PAINT)
GPU_paint_set_mipmap(1);
@@ -1446,6 +1494,8 @@ static void RestoreState(bContext *C)
win->queue= queue_back;
+ GPU_state_init();
+
glPopAttrib();
}
@@ -1574,6 +1624,802 @@ void VIEW3D_OT_game_start(wmOperatorType *ot)
ot->poll= game_engine_poll;
}
+
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+#define FLY_MODAL_CANCEL 1
+#define FLY_MODAL_CONFIRM 2
+#define FLY_MODAL_ACCELERATE 3
+#define FLY_MODAL_DECELERATE 4
+#define FLY_MODAL_PAN_ENABLE 5
+#define FLY_MODAL_PAN_DISABLE 6
+#define FLY_MODAL_DIR_FORWARD 7
+#define FLY_MODAL_DIR_BACKWARD 8
+#define FLY_MODAL_DIR_LEFT 9
+#define FLY_MODAL_DIR_RIGHT 10
+#define FLY_MODAL_DIR_UP 11
+#define FLY_MODAL_DIR_DOWN 12
+#define FLY_MODAL_AXIS_LOCK_X 13
+#define FLY_MODAL_AXIS_LOCK_Z 14
+#define FLY_MODAL_PRECISION_ENABLE 15
+#define FLY_MODAL_PRECISION_DISABLE 16
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+void fly_modal_keymap(wmKeyConfig *keyconf)
+{
+ static EnumPropertyItem modal_items[] = {
+ {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+ {FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+ {FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
+ {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
+
+ {FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan Enable", ""},
+ {FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan Disable", ""},
+
+ {FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Fly Forward", ""},
+ {FLY_MODAL_DIR_BACKWARD,"BACKWARD", 0, "Fly Backward", ""},
+ {FLY_MODAL_DIR_LEFT, "LEFT", 0, "Fly Left", ""},
+ {FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Fly Right", ""},
+ {FLY_MODAL_DIR_UP, "UP", 0, "Fly Up", ""},
+ {FLY_MODAL_DIR_DOWN, "DOWN", 0, "Fly Down", ""},
+
+ {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"},
+ {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"},
+
+ {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision Enable", ""},
+ {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision Disable", ""},
+
+ {0, NULL, 0, NULL, NULL}};
+
+ wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Fly Modal");
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if(keymap) return;
+
+ keymap= WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items);
+
+ /* items for modal map */
+ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CANCEL);
+ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CANCEL);
+
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM);
+ WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM);
+
+ WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE);
+ WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE);
+ WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE);
+ WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE);
+
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE);
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */
+
+ /* WASD */
+ WM_modalkeymap_add_item(keymap, WKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_FORWARD);
+ WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_BACKWARD);
+ WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_LEFT);
+ WM_modalkeymap_add_item(keymap, DKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_RIGHT);
+ WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_UP);
+ WM_modalkeymap_add_item(keymap, FKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_DOWN);
+
+ WM_modalkeymap_add_item(keymap, XKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_X);
+ WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_Z);
+
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_PRECISION_ENABLE);
+ WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PRECISION_DISABLE);
+
+ /* assign map to operators */
+ WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly");
+
+}
+
+typedef struct FlyInfo {
+ /* context stuff */
+ RegionView3D *rv3d;
+ View3D *v3d;
+ ARegion *ar;
+ Scene *scene;
+
+ wmTimer *timer; /* needed for redraws */
+
+ short state;
+ short use_precision;
+ short redraw;
+ short mval[2];
+
+ /* fly state state */
+ float speed; /* the speed the view is moving per redraw */
+ short axis; /* Axis index to move allong by default Z to move allong the view */
+ short pan_view; /* when true, pan the view instead of rotating */
+
+ /* relative view axis locking - xlock, zlock
+ 0; disabled
+ 1; enabled but not checking because mouse hasnt moved outside the margin since locking was checked an not needed
+ when the mouse moves, locking is set to 2 so checks are done.
+ 2; mouse moved and checking needed, if no view altering is donem its changed back to 1 */
+ short xlock, zlock;
+ float xlock_momentum, zlock_momentum; /* nicer dynamics */
+ float grid; /* world scale 1.0 default */
+
+ /* backup values */
+ float dist_backup; /* backup the views distance since we use a zero dist for fly mode */
+ float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */
+ float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */
+ short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */
+
+ /* compare between last state */
+ double time_lastwheel; /* used to accelerate when using the mousewheel a lot */
+ double time_lastdraw; /* time between draws */
+
+ /* use for some lag */
+ float dvec_prev[3]; /* old for some lag */
+
+} FlyInfo;
+
+/* FlyInfo->state */
+#define FLY_RUNNING 0
+#define FLY_CANCEL 1
+#define FLY_CONFIRM 2
+
+int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
+{
+ float upvec[3]; // tmp
+ float mat[3][3];
+
+ fly->rv3d= CTX_wm_region_view3d(C);
+ fly->v3d = CTX_wm_view3d(C);
+ fly->ar = CTX_wm_region(C);
+ fly->scene= CTX_data_scene(C);
+
+ if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->id.lib) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
+ return FALSE;
+ }
+
+ if(fly->v3d->ob_centre) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view is locked to an object");
+ return FALSE;
+ }
+
+ if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->constraints.first) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
+ return FALSE;
+ }
+
+ fly->state= FLY_RUNNING;
+ fly->speed= 0.0f;
+ fly->axis= 2;
+ fly->pan_view= FALSE;
+ fly->xlock= FALSE;
+ fly->zlock= TRUE;
+ fly->xlock_momentum=0.0f;
+ fly->zlock_momentum=0.0f;
+ fly->grid= 1.0f;
+ fly->use_precision= 0;
+
+ fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f;
+
+ fly->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
+
+
+ /* we have to rely on events to give proper mousecoords after a warp_pointer */
+//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]);
+ //fly->mval[0]= (fly->sa->winx)/2;
+ //fly->mval[1]= (fly->sa->winy)/2;
+
+ fly->mval[0] = event->x - fly->ar->winrct.xmin;
+ fly->mval[1] = event->y - fly->ar->winrct.ymin;
+
+
+ fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer();
+
+ fly->rv3d->rflag |= RV3D_FLYMODE; /* so we draw the corner margins */
+
+ /* detect weather to start with Z locking */
+ upvec[0]=1.0f; upvec[1]=0.0f; upvec[2]=0.0f;
+ Mat3CpyMat4(mat, fly->rv3d->viewinv);
+ Mat3MulVecfl(mat, upvec);
+ if (fabs(upvec[2]) < 0.1)
+ fly->zlock = 1;
+ upvec[0]=0; upvec[1]=0; upvec[2]=0;
+
+ fly->persp_backup= fly->rv3d->persp;
+ fly->dist_backup= fly->rv3d->dist;
+ if (fly->rv3d->persp==V3D_CAMOB) {
+ /* store the origoinal camera loc and rot */
+ VECCOPY(fly->ofs_backup, fly->v3d->camera->loc);
+ VECCOPY(fly->rot_backup, fly->v3d->camera->rot);
+
+ where_is_object(fly->scene, fly->v3d->camera);
+ VECCOPY(fly->rv3d->ofs, fly->v3d->camera->obmat[3]);
+ VecMulf(fly->rv3d->ofs, -1.0f); /*flip the vector*/
+
+ fly->rv3d->dist=0.0;
+ fly->rv3d->viewbut=0;
+
+ /* used for recording */
+//XXX2.5 if(v3d->camera->ipoflag & OB_ACTION_OB)
+//XXX2.5 actname= "Object";
+
+ } else {
+ /* perspective or ortho */
+ if (fly->rv3d->persp==V3D_ORTHO)
+ fly->rv3d->persp= V3D_PERSP; /*if ortho projection, make perspective */
+ QUATCOPY(fly->rot_backup, fly->rv3d->viewquat);
+ VECCOPY(fly->ofs_backup, fly->rv3d->ofs);
+ fly->rv3d->dist= 0.0;
+
+ upvec[2]= fly->dist_backup; /*x and y are 0*/
+ Mat3MulVecfl(mat, upvec);
+ VecSubf(fly->rv3d->ofs, fly->rv3d->ofs, upvec);
+ /*Done with correcting for the dist*/
+ }
+
+ return 1;
+}
+
+static int flyEnd(bContext *C, FlyInfo *fly)
+{
+ RegionView3D *rv3d= fly->rv3d;
+ View3D *v3d = fly->v3d;
+
+ float upvec[3];
+
+ if(fly->state == FLY_RUNNING)
+ return OPERATOR_RUNNING_MODAL;
+
+ WM_event_remove_window_timer(CTX_wm_window(C), fly->timer);
+
+ rv3d->dist= fly->dist_backup;
+
+ if (fly->state == FLY_CANCEL) {
+ /* Revert to original view? */
+ if (fly->persp_backup==V3D_CAMOB) { /* a camera view */
+ rv3d->viewbut=1;
+ VECCOPY(v3d->camera->loc, fly->ofs_backup);
+ VECCOPY(v3d->camera->rot, fly->rot_backup);
+ DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
+ } else {
+ /* Non Camera we need to reset the view back to the original location bacause the user canceled*/
+ QUATCOPY(rv3d->viewquat, fly->rot_backup);
+ VECCOPY(rv3d->ofs, fly->ofs_backup);
+ rv3d->persp= fly->persp_backup;
+ }
+ }
+ else if (fly->persp_backup==V3D_CAMOB) { /* camera */
+ float mat3[3][3];
+ Mat3CpyMat4(mat3, v3d->camera->obmat);
+ Mat3ToCompatibleEul(mat3, v3d->camera->rot, fly->rot_backup);
+
+ DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
+#if 0 //XXX2.5
+ if (IS_AUTOKEY_MODE(NORMAL)) {
+ allqueue(REDRAWIPO, 0);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWTIME, 0);
+ }
+#endif
+ }
+ else { /* not camera */
+ /* Apply the fly mode view */
+ /*restore the dist*/
+ float mat[3][3];
+ upvec[0]= upvec[1]= 0;
+ upvec[2]= fly->dist_backup; /*x and y are 0*/
+ Mat3CpyMat4(mat, rv3d->viewinv);
+ Mat3MulVecfl(mat, upvec);
+ VecAddf(rv3d->ofs, rv3d->ofs, upvec);
+ /*Done with correcting for the dist */
+ }
+
+ rv3d->rflag &= ~RV3D_FLYMODE;
+//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
+
+
+ if(fly->state == FLY_CONFIRM) {
+ MEM_freeN(fly);
+ return OPERATOR_FINISHED;
+ }
+
+ MEM_freeN(fly);
+ return OPERATOR_CANCELLED;
+}
+
+void flyEvent(FlyInfo *fly, wmEvent *event)
+{
+ if (event->type == TIMER) {
+ fly->redraw = 1;
+ }
+ else if (event->type == MOUSEMOVE) {
+ fly->mval[0] = event->x - fly->ar->winrct.xmin;
+ fly->mval[1] = event->y - fly->ar->winrct.ymin;
+ } /* handle modal keymap first */
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case FLY_MODAL_CANCEL:
+ fly->state = FLY_CANCEL;
+ break;
+ case FLY_MODAL_CONFIRM:
+ fly->state = FLY_CONFIRM;
+ break;
+
+ case FLY_MODAL_ACCELERATE:
+ {
+ double time_currwheel;
+ float time_wheel;
+
+ time_currwheel= PIL_check_seconds_timer();
+ time_wheel = (float)(time_currwheel - fly->time_lastwheel);
+ fly->time_lastwheel = time_currwheel;
+ /*printf("Wheel %f\n", time_wheel);*/
+ /*Mouse wheel delays range from 0.5==slow to 0.01==fast*/
+ time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */
+
+ if (fly->speed<0.0f) fly->speed= 0.0f;
+ else {
+ if (event->shift)
+ fly->speed+= fly->grid*time_wheel*0.1;
+ else
+ fly->speed+= fly->grid*time_wheel;
+ }
+ break;
+ }
+ case FLY_MODAL_DECELERATE:
+ {
+ double time_currwheel;
+ float time_wheel;
+
+ time_currwheel= PIL_check_seconds_timer();
+ time_wheel = (float)(time_currwheel - fly->time_lastwheel);
+ fly->time_lastwheel = time_currwheel;
+ time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */
+
+ if (fly->speed>0) fly->speed=0;
+ else {
+ if (event->shift)
+ fly->speed-= fly->grid*time_wheel*0.1;
+ else
+ fly->speed-= fly->grid*time_wheel;
+ }
+ break;
+ }
+ case FLY_MODAL_PAN_ENABLE:
+ fly->pan_view= TRUE;
+ break;
+ case FLY_MODAL_PAN_DISABLE:
+//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]);
+ fly->pan_view= FALSE;
+ break;
+
+ /* impliment WASD keys */
+ case FLY_MODAL_DIR_FORWARD:
+ if (fly->speed < 0.0f) fly->speed= -fly->speed; /* flip speed rather then stopping, game like motion */
+ else fly->speed += fly->grid; /* increse like mousewheel if were alredy moving in that difection*/
+ fly->axis= 2;
+ break;
+ case FLY_MODAL_DIR_BACKWARD:
+ if (fly->speed>0) fly->speed= -fly->speed;
+ else fly->speed -= fly->grid;
+ fly->axis= 2;
+ break;
+ case FLY_MODAL_DIR_LEFT:
+ if (fly->speed < 0.0f) fly->speed= -fly->speed;
+ fly->axis= 0;
+ break;
+ case FLY_MODAL_DIR_RIGHT:
+ if (fly->speed > 0.0f) fly->speed= -fly->speed;
+ fly->axis= 0;
+ break;
+
+ case FLY_MODAL_DIR_UP:
+ if (fly->speed < 0.0f) fly->speed= -fly->speed;
+ fly->axis= 1;
+ break;
+
+ case FLY_MODAL_DIR_DOWN:
+ if (fly->speed > 0.0f) fly->speed= -fly->speed;
+ fly->axis= 1;
+ break;
+
+ case FLY_MODAL_AXIS_LOCK_X:
+ if (fly->xlock) fly->xlock=0;
+ else {
+ fly->xlock = 2;
+ fly->xlock_momentum = 0.0;
+ }
+ break;
+ case FLY_MODAL_AXIS_LOCK_Z:
+ if (fly->zlock) fly->zlock=0;
+ else {
+ fly->zlock = 2;
+ fly->zlock_momentum = 0.0;
+ }
+ break;
+
+ case FLY_MODAL_PRECISION_ENABLE:
+ fly->use_precision= TRUE;
+ break;
+ case FLY_MODAL_PRECISION_DISABLE:
+ fly->use_precision= FALSE;
+ break;
+
+ }
+ }
+}
+
+//int fly_exec(bContext *C, wmOperator *op)
+int flyApply(FlyInfo *fly)
+{
+ /*
+ fly mode - Shift+F
+ a fly loop where the user can move move the view as if they are flying
+ */
+ RegionView3D *rv3d= fly->rv3d;
+ View3D *v3d = fly->v3d;
+ ARegion *ar = fly->ar;
+ Scene *scene= fly->scene;
+
+ float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */
+ dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */
+
+ /* Camera Uprighting variables */
+ upvec[3]={0,0,0}, /* stores the view's up vector */
+
+ moffset[2], /* mouse offset from the views center */
+ tmp_quat[4]; /* used for rotating the view */
+
+ int cent_orig[2], /* view center */
+//XXX- can avoid using // cent[2], /* view center modified */
+ xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */
+ unsigned char
+ apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/
+
+ /* for recording */
+#if 0 //XXX2.5 todo, get animation recording working again.
+ int playing_anim = 0; //XXX has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
+ int cfra = -1; /*so the first frame always has a key added */
+ char *actname="";
+#endif
+ /* the dist defines a vector that is infront of the offset
+ to rotate the view about.
+ this is no good for fly mode because we
+ want to rotate about the viewers center.
+ but to correct the dist removal we must
+ alter offset so the view doesn't jump. */
+
+ xmargin= ar->winx/20.0f;
+ ymargin= ar->winy/20.0f;
+
+ cent_orig[0]= ar->winrct.xmin + ar->winx/2;
+ cent_orig[1]= ar->winrct.ymin + ar->winy/2;
+
+ {
+
+ /* mouse offset from the center */
+ moffset[0]= fly->mval[0]- ar->winx/2;
+ moffset[1]= fly->mval[1]- ar->winy/2;
+
+ /* enforce a view margin */
+ if (moffset[0]>xmargin) moffset[0]-=xmargin;
+ else if (moffset[0] < -xmargin) moffset[0]+=xmargin;
+ else moffset[0]=0;
+
+ if (moffset[1]>ymargin) moffset[1]-=ymargin;
+ else if (moffset[1] < -ymargin) moffset[1]+=ymargin;
+ else moffset[1]=0;
+
+
+ /* scale the mouse movement by this value - scales mouse movement to the view size
+ * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y)
+ *
+ * the mouse moves isnt linear */
+
+ if(moffset[0]) {
+ moffset[0] /= ar->winx - (xmargin*2);
+ moffset[0] *= fabs(moffset[0]);
+ }
+
+ if(moffset[1]) {
+ moffset[1] /= ar->winy - (ymargin*2);
+ moffset[1] *= fabs(moffset[1]);
+ }
+
+ /* Should we redraw? */
+ if(fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) {
+ float dvec_tmp[3];
+ double time_current, time_redraw; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */
+ float time_redraw_clamped;
+
+ time_current= PIL_check_seconds_timer();
+ time_redraw= (float)(time_current - fly->time_lastdraw);
+ time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamt the redraw time to avoid jitter in roll correction */
+ fly->time_lastdraw= time_current;
+ /*fprintf(stderr, "%f\n", time_redraw);*/ /* 0.002 is a small redraw 0.02 is larger */
+
+ /* Scale the time to use shift to scale the speed down- just like
+ shift slows many other areas of blender down */
+ if (fly->use_precision)
+ fly->speed= fly->speed * (1.0f-time_redraw_clamped);
+
+ Mat3CpyMat4(mat, rv3d->viewinv);
+
+ if (fly->pan_view==TRUE) {
+ /* pan only */
+ dvec_tmp[0]= -moffset[0];
+ dvec_tmp[1]= -moffset[1];
+ dvec_tmp[2]= 0;
+
+ if (fly->use_precision) {
+ dvec_tmp[0] *= 0.1;
+ dvec_tmp[1] *= 0.1;
+ }
+
+ Mat3MulVecfl(mat, dvec_tmp);
+ VecMulf(dvec_tmp, time_redraw*200.0 * fly->grid);
+
+ } else {
+ float roll; /* similar to the angle between the camera's up and the Z-up, but its very rough so just roll*/
+
+ /* rotate about the X axis- look up/down */
+ if (moffset[1]) {
+ upvec[0]=1;
+ upvec[1]=0;
+ upvec[2]=0;
+ Mat3MulVecfl(mat, upvec);
+ VecRotToQuat( upvec, (float)moffset[1]*-time_redraw*20, tmp_quat); /* Rotate about the relative up vec */
+ QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ if (fly->xlock) fly->xlock = 2; /*check for rotation*/
+ if (fly->zlock) fly->zlock = 2;
+ fly->xlock_momentum= 0.0f;
+ }
+
+ /* rotate about the Y axis- look left/right */
+ if (moffset[0]) {
+
+ /* if we're upside down invert the moffset */
+ upvec[0]=0;
+ upvec[1]=1;
+ upvec[2]=0;
+ Mat3MulVecfl(mat, upvec);
+
+ if(upvec[2] < 0.0f)
+ moffset[0]= -moffset[0];
+
+ /* make the lock vectors */
+ if (fly->zlock) {
+ upvec[0]=0;
+ upvec[1]=0;
+ upvec[2]=1;
+ } else {
+ upvec[0]=0;
+ upvec[1]=1;
+ upvec[2]=0;
+ Mat3MulVecfl(mat, upvec);
+ }
+
+ VecRotToQuat( upvec, (float)moffset[0]*time_redraw*20, tmp_quat); /* Rotate about the relative up vec */
+ QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ if (fly->xlock) fly->xlock = 2;/*check for rotation*/
+ if (fly->zlock) fly->zlock = 2;
+ }
+
+ if (fly->zlock==2) {
+ upvec[0]=1;
+ upvec[1]=0;
+ upvec[2]=0;
+ Mat3MulVecfl(mat, upvec);
+
+ /*make sure we have some z rolling*/
+ if (fabs(upvec[2]) > 0.00001f) {
+ roll= upvec[2]*5;
+ upvec[0]=0; /*rotate the view about this axis*/
+ upvec[1]=0;
+ upvec[2]=1;
+
+ Mat3MulVecfl(mat, upvec);
+ VecRotToQuat( upvec, roll*time_redraw_clamped*fly->zlock_momentum*0.1, tmp_quat); /* Rotate about the relative up vec */
+ QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ fly->zlock_momentum += 0.05f;
+ } else {
+ fly->zlock=1; /* dont check until the view rotates again */
+ fly->zlock_momentum= 0.0f;
+ }
+ }
+
+ if (fly->xlock==2 && moffset[1]==0) { /*only apply xcorrect when mouse isnt applying x rot*/
+ upvec[0]=0;
+ upvec[1]=0;
+ upvec[2]=1;
+ Mat3MulVecfl(mat, upvec);
+ /*make sure we have some z rolling*/
+ if (fabs(upvec[2]) > 0.00001) {
+ roll= upvec[2] * -5;
+
+ upvec[0]= 1.0f; /*rotate the view about this axis*/
+ upvec[1]= 0.0f;
+ upvec[2]= 0.0f;
+
+ Mat3MulVecfl(mat, upvec);
+
+ VecRotToQuat( upvec, roll*time_redraw_clamped*fly->xlock_momentum*0.1f, tmp_quat); /* Rotate about the relative up vec */
+ QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
+
+ fly->xlock_momentum += 0.05f;
+ } else {
+ fly->xlock=1; /* see above */
+ fly->xlock_momentum= 0.0f;
+ }
+ }
+
+
+ if (apply_rotation) {
+ /* Normal operation */
+ /* define dvec, view direction vector */
+ dvec_tmp[0]= dvec_tmp[1]= dvec_tmp[2]= 0.0f;
+ /* move along the current axis */
+ dvec_tmp[fly->axis]= 1.0f;
+
+ Mat3MulVecfl(mat, dvec_tmp);
+
+ VecMulf(dvec_tmp, fly->speed * time_redraw * 0.25f);
+ }
+ }
+
+ /* impose a directional lag */
+ VecLerpf(dvec, dvec_tmp, fly->dvec_prev, (1.0f/(1.0f+(time_redraw*5.0f))));
+
+ if (rv3d->persp==V3D_CAMOB) {
+ if (v3d->camera->protectflag & OB_LOCK_LOCX)
+ dvec[0] = 0.0;
+ if (v3d->camera->protectflag & OB_LOCK_LOCY)
+ dvec[1] = 0.0;
+ if (v3d->camera->protectflag & OB_LOCK_LOCZ)
+ dvec[2] = 0.0;
+ }
+
+ VecAddf(rv3d->ofs, rv3d->ofs, dvec);
+#if 0 //XXX2.5
+ if (fly->zlock && fly->xlock)
+ headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ else if (fly->zlock)
+ headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ else if (fly->xlock)
+ headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ else
+ headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+#endif
+
+//XXX2.5 do_screenhandlers(G.curscreen); /* advance the next frame */
+
+ /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */
+ if (rv3d->persp==V3D_CAMOB) {
+ rv3d->persp= V3D_PERSP; /*set this so setviewmatrixview3d uses the ofs and quat instead of the camera */
+ setviewmatrixview3d(scene, v3d, rv3d);
+
+ setcameratoview3d(v3d, rv3d, v3d->camera);
+
+ { //XXX - some reason setcameratoview3d doesnt copy, shouldnt not be needed!
+ VECCOPY(v3d->camera->loc, rv3d->ofs);
+ VecNegf(v3d->camera->loc);
+ }
+
+ rv3d->persp= V3D_CAMOB;
+#if 0 //XXX2.5
+ /* record the motion */
+ if (IS_AUTOKEY_MODE(NORMAL) && (!playing_anim || cfra != G.scene->r.cfra)) {
+ cfra = G.scene->r.cfra;
+
+ if (fly->xlock || fly->zlock || moffset[0] || moffset[1]) {
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_X, 0);
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Y, 0);
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Z, 0);
+ }
+ if (fly->speed) {
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_X, 0);
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Y, 0);
+ insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Z, 0);
+ }
+ }
+#endif
+ }
+//XXX2.5 scrarea_do_windraw(curarea);
+//XXX2.5 screen_swapbuffers();
+ } else
+ /*were not redrawing but we need to update the time else the view will jump */
+ fly->time_lastdraw= PIL_check_seconds_timer();
+ /* end drawing */
+ VECCOPY(fly->dvec_prev, dvec);
+ }
+
+/* moved to flyEnd() */
+
+ return OPERATOR_FINISHED;
+}
+
+
+
+static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ RegionView3D *rv3d= CTX_wm_region_view3d(C);
+ FlyInfo *fly;
+
+ if(rv3d->viewlock)
+ return OPERATOR_CANCELLED;
+
+ fly= MEM_callocN(sizeof(FlyInfo), "FlyOperation");
+
+ op->customdata= fly;
+
+ if(initFlyInfo(C, fly, op, event)==FALSE) {
+ MEM_freeN(op->customdata);
+ return OPERATOR_CANCELLED;
+ }
+
+ flyEvent(fly, event);
+
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int fly_cancel(bContext *C, wmOperator *op)
+{
+ FlyInfo *fly = op->customdata;
+
+ fly->state = FLY_CANCEL;
+ flyEnd(C, fly);
+ op->customdata= NULL;
+
+ return OPERATOR_CANCELLED;
+}
+
+static int fly_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ int exit_code;
+
+ FlyInfo *fly = op->customdata;
+
+ fly->redraw= 0;
+
+ flyEvent(fly, event);
+
+ if(event->type==TIMER)
+ flyApply(fly);
+
+ if(fly->redraw) {;
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
+
+ exit_code = flyEnd(C, fly);
+
+ if(exit_code!=OPERATOR_RUNNING_MODAL)
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return exit_code;
+}
+
+void VIEW3D_OT_fly(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name= "Fly Navigation";
+ ot->description= "Interactively fly around the scene.";
+ ot->idname= "VIEW3D_OT_fly";
+
+ /* api callbacks */
+ ot->invoke= fly_invoke;
+ ot->cancel= fly_cancel;
+ ot->modal= fly_modal;
+ ot->poll= ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag= OPTYPE_BLOCKING;
+
+}
+
/* ************************************** */
void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, float vec[3])