static void applyAxisConstraintVec(TransInfo *t, TransData *td, const float in[3], float out[3], float pvec[3])
{
	copy_v3_v3(out, in);
	if (!td && t->con.mode & CON_APPLY) {
		mul_m3_v3(t->con.pmtx, out);

		// With snap, a projection is alright, no need to correct for view alignment
		if (!(!ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID) && activeSnap(t))) {
			if (getConstraintSpaceDimension(t) == 2) {
				if (out[0] != 0.0f || out[1] != 0.0f || out[2] != 0.0f) {
					planeProjection(t, in, out);
				}
			}
			else if (getConstraintSpaceDimension(t) == 1) {
				float c[3];

				if (t->con.mode & CON_AXIS0) {
					copy_v3_v3(c, t->con.mtx[0]);
				}
				else if (t->con.mode & CON_AXIS1) {
					copy_v3_v3(c, t->con.mtx[1]);
				}
				else if (t->con.mode & CON_AXIS2) {
					copy_v3_v3(c, t->con.mtx[2]);
				}
				axisProjection(t, c, in, out);
			}
		}
		postConstraintChecks(t, out, pvec);
	}
}
示例#2
0
void applySnapping(TransInfo *t, float *vec)
{
	/* project is not applied this way */
	if (t->tsnap.project)
		return;
	
	if (t->tsnap.status & SNAP_FORCED) {
		t->tsnap.targetSnap(t);
	
		t->tsnap.applySnap(t, vec);
	}
	else if (!ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID) && activeSnap(t)) {
		double current = PIL_check_seconds_timer();
		
		// Time base quirky code to go around findnearest slowness
		/* !TODO! add exception for object mode, no need to slow it down then */
		if (current - t->tsnap.last >= 0.01) {
			t->tsnap.calcSnap(t, vec);
			t->tsnap.targetSnap(t);
	
			t->tsnap.last = current;
		}
		if (validSnap(t)) {
			t->tsnap.applySnap(t, vec);
		}
	}
}
示例#3
0
void applyProject(TransInfo *t)
{
	/* XXX FLICKER IN OBJECT MODE */
	if ((t->tsnap.project) && activeSnap(t) && (t->flag & T_NO_PROJECT) == 0) {
		TransData *td = t->data;
		float tvec[3];
		float imat[4][4];
		int i;
	
		if (t->flag & (T_EDIT | T_POSE)) {
			Object *ob = t->obedit ? t->obedit : t->poseobj;
			invert_m4_m4(imat, ob->obmat);
		}

		for (i = 0; i < t->total; i++, td++) {
			float iloc[3], loc[3], no[3];
			float mval_fl[2];
			float dist_px = TRANSFORM_DIST_MAX_PX;
			
			if (td->flag & TD_NOACTION)
				break;
			
			if (td->flag & TD_SKIP)
				continue;

			if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f))
				continue;
			
			copy_v3_v3(iloc, td->loc);
			if (t->flag & (T_EDIT | T_POSE)) {
				Object *ob = t->obedit ? t->obedit : t->poseobj;
				mul_m4_v3(ob->obmat, iloc);
			}
			else if (t->flag & T_OBJECT) {
				/* TODO(sergey): Ideally force update is not needed here. */
				td->ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
				BKE_object_handle_update(G.main->eval_ctx, t->scene, td->ob);
				copy_v3_v3(iloc, td->ob->obmat[3]);
			}
			
			if (ED_view3d_project_float_global(t->ar, iloc, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
				if (snapObjectsTransform(
				        t, mval_fl, &dist_px,
				        loc, no))
				{
//					if (t->flag & (T_EDIT|T_POSE)) {
//						mul_m4_v3(imat, loc);
//					}

					sub_v3_v3v3(tvec, loc, iloc);

					mul_m3_v3(td->smtx, tvec);

					add_v3_v3(td->loc, tvec);

					if (t->tsnap.align && (t->flag & T_OBJECT)) {
						/* handle alignment as well */
						const float *original_normal;
						float mat[3][3];

						/* In pose mode, we want to align normals with Y axis of bones... */
						original_normal = td->axismtx[2];

						rotation_between_vecs_to_mat3(mat, original_normal, no);

						transform_data_ext_rotate(td, mat, true);

						/* TODO support constraints for rotation too? see ElementRotation */
					}
				}
			}
			
			//XXX constraintTransLim(t, td);
		}
	}
}
示例#4
0
void applyGridAbsolute(TransInfo *t)
{
	float grid_size = 0.0f;
	GearsType grid_action;
	TransData *td;
	float (*obmat)[4] = NULL;
	bool use_obmat = false;
	int i;
	
	if (!(activeSnap(t) && (ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID))))
		return;
	
	grid_action = BIG_GEARS;
	if (t->modifiers & MOD_PRECISION)
		grid_action = SMALL_GEARS;
	
	switch (grid_action) {
		case NO_GEARS: grid_size = t->snap_spatial[0]; break;
		case BIG_GEARS: grid_size = t->snap_spatial[1]; break;
		case SMALL_GEARS: grid_size = t->snap_spatial[2]; break;
	}
	/* early exit on unusable grid size */
	if (grid_size == 0.0f)
		return;
	
	if (t->flag & (T_EDIT | T_POSE)) {
		Object *ob = t->obedit ? t->obedit : t->poseobj;
		obmat = ob->obmat;
		use_obmat = true;
	}
	
	for (i = 0, td = t->data; i < t->total; i++, td++) {
		float iloc[3], loc[3], tvec[3];
		
		if (td->flag & TD_NOACTION)
			break;
		
		if (td->flag & TD_SKIP)
			continue;
		
		if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f))
			continue;
		
		copy_v3_v3(iloc, td->loc);
		if (use_obmat) {
			mul_m4_v3(obmat, iloc);
		}
		else if (t->flag & T_OBJECT) {
			td->ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
			BKE_object_handle_update(G.main->eval_ctx, t->scene, td->ob);
			copy_v3_v3(iloc, td->ob->obmat[3]);
		}
		
		mul_v3_v3fl(loc, iloc, 1.0f / grid_size);
		loc[0] = roundf(loc[0]);
		loc[1] = roundf(loc[1]);
		loc[2] = roundf(loc[2]);
		mul_v3_fl(loc, grid_size);

		sub_v3_v3v3(tvec, loc, iloc);
		mul_m3_v3(td->smtx, tvec);
		add_v3_v3(td->loc, tvec);
	}
}
示例#5
0
void drawSnapping(const struct bContext *C, TransInfo *t)
{
	unsigned char col[4], selectedCol[4], activeCol[4];
	
	if (!activeSnap(t))
		return;
	
	UI_GetThemeColor3ubv(TH_TRANSFORM, col);
	col[3] = 128;
	
	UI_GetThemeColor3ubv(TH_SELECT, selectedCol);
	selectedCol[3] = 128;
	
	UI_GetThemeColor3ubv(TH_ACTIVE, activeCol);
	activeCol[3] = 192;
	
	if (t->spacetype == SPACE_VIEW3D) {
		if (validSnap(t)) {
			TransSnapPoint *p;
			View3D *v3d = CTX_wm_view3d(C);
			RegionView3D *rv3d = CTX_wm_region_view3d(C);
			float imat[4][4];
			float size;
			
			glDisable(GL_DEPTH_TEST);
			
			size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
			
			invert_m4_m4(imat, rv3d->viewmat);
			
			for (p = t->tsnap.points.first; p; p = p->next) {
				if (p == t->tsnap.selectedPoint) {
					glColor4ubv(selectedCol);
				}
				else {
					glColor4ubv(col);
				}
				
				drawcircball(GL_LINE_LOOP, p->co, ED_view3d_pixel_size(rv3d, p->co) * size * 0.75f, imat);
			}
			
			if (t->tsnap.status & POINT_INIT) {
				glColor4ubv(activeCol);
				
				drawcircball(GL_LINE_LOOP, t->tsnap.snapPoint, ED_view3d_pixel_size(rv3d, t->tsnap.snapPoint) * size, imat);
			}
			
			/* draw normal if needed */
			if (usingSnappingNormal(t) && validSnappingNormal(t)) {
				glColor4ubv(activeCol);
				
				glBegin(GL_LINES);
				glVertex3f(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]);
				glVertex3f(t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0],
				           t->tsnap.snapPoint[1] + t->tsnap.snapNormal[1],
				           t->tsnap.snapPoint[2] + t->tsnap.snapNormal[2]);
				glEnd();
			}
			
			if (v3d->zbuf)
				glEnable(GL_DEPTH_TEST);
		}
	}
	else if (t->spacetype == SPACE_IMAGE) {
		if (validSnap(t)) {
			/* This will not draw, and Im nor sure why - campbell */
#if 0
			float xuser_asp, yuser_asp;
			int wi, hi;
			float w, h;
			
			calc_image_view(G.sima, 'f');   // float
			myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
			glLoadIdentity();
			
			ED_space_image_get_aspect(t->sa->spacedata.first, &xuser_aspx, &yuser_asp);
			ED_space_image_width(t->sa->spacedata.first, &wi, &hi);
			w = (((float)wi) / IMG_SIZE_FALLBACK) * G.sima->zoom * xuser_asp;
			h = (((float)hi) / IMG_SIZE_FALLBACK) * G.sima->zoom * yuser_asp;
			
			cpack(0xFFFFFF);
			glTranslate2fv(t->tsnap.snapPoint);
			
			//glRectf(0, 0, 1, 1);
			
			setlinestyle(0);
			cpack(0x0);
			fdrawline(-0.020 / w, 0, -0.1 / w, 0);
			fdrawline(0.1 / w, 0, 0.020 / w, 0);
			fdrawline(0, -0.020 / h, 0, -0.1 / h);
			fdrawline(0, 0.1 / h, 0, 0.020 / h);
			
			glTranslatef(-t->tsnap.snapPoint[0], -t->tsnap.snapPoint[1], 0.0f);
			setlinestyle(0);
#endif
		}
	}
	else if (t->spacetype == SPACE_NODE) {
		if (validSnap(t)) {
			ARegion *ar = CTX_wm_region(C);
			TransSnapPoint *p;
			float size;
			
			size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
			
			glEnable(GL_BLEND);
			
			for (p = t->tsnap.points.first; p; p = p->next) {
				if (p == t->tsnap.selectedPoint) {
					glColor4ubv(selectedCol);
				}
				else {
					glColor4ubv(col);
				}
				
				ED_node_draw_snap(&ar->v2d, p->co, size, 0);
			}
			
			if (t->tsnap.status & POINT_INIT) {
				glColor4ubv(activeCol);
				
				ED_node_draw_snap(&ar->v2d, t->tsnap.snapPoint, size, t->tsnap.snapNodeBorder);
			}
			
			glDisable(GL_BLEND);
		}
	}
}