Esempio n. 1
0
//=============================================================================
Obb3::Obb3 (const Point3 & center, const Vector3 & x, const Vector3 & y, const Vector3 & z) :
    center(center)
{
    u[0] = x;
    u[1] = y;
    u[2] = z;

    for (uint i = 0; i < 3; ++i)
        extent[i] = Normalize2(u[i]);

}
Esempio n. 2
0
//=============================================================================
Obb2::Obb2 (
    const Point2 & center,
    const Vector2 & x,
    const Vector2 & y
) :
    center(center)
{
    u[0] = x;
    u[1] = y;

    for (uint i = 0; i < 2; ++i)
        extent[i] = Normalize2(u[i]);

}
Esempio n. 3
0
/* draw a given stroke in 2d */
static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, 
							short debug, int offsx, int offsy, int winx, int winy)
{
	/* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better
	 * 	- 'smooth' opengl lines are also required if Image Editor 'image-based' stroke
	 */
	if ( (thickness < GP_DRAWTHICKNESS_SPECIAL) || 
		 ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) ) 
	{
		bGPDspoint *pt;
		int i;
		
		glBegin(GL_LINE_STRIP);
		for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
			if (sflag & GP_STROKE_2DSPACE) {
				glVertex2f(pt->x, pt->y);
			}
			else if (sflag & GP_STROKE_2DIMAGE) {
				const float x= (pt->x * winx) + offsx;
				const float y= (pt->y * winy) + offsy;
				
				glVertex2f(x, y);
			}
			else {
				const float x= (pt->x / 100 * winx);
				const float y= (pt->y / 100 * winy);
				
				glVertex2f(x, y);
			}
		}
		glEnd();
	}
	
	/* tesselation code - draw stroke as series of connected quads with connection
	 * edges rotated to minimise shrinking artifacts, and rounded endcaps
	 */
	else 
	{ 
		bGPDspoint *pt1, *pt2;
		float pm[2];
		int i;
		
		glShadeModel(GL_FLAT);
		glBegin(GL_QUADS);
		
		for (i=0, pt1=points, pt2=points+1; i < (totpoints-1); i++, pt1++, pt2++) {
			float s0[2], s1[2];		/* segment 'center' points */
			float t0[2], t1[2];		/* tesselated coordinates */
			float m1[2], m2[2];		/* gradient and normal */
			float mt[2], sc[2];		/* gradient for thickness, point for end-cap */
			float pthick;			/* thickness at segment point */
			
			/* get x and y coordinates from points */
			if (sflag & GP_STROKE_2DSPACE) {
				s0[0]= pt1->x; 		s0[1]= pt1->y;
				s1[0]= pt2->x;		s1[1]= pt2->y;
			}
			else if (sflag & GP_STROKE_2DIMAGE) {
				s0[0]= (pt1->x * winx) + offsx; 		
				s0[1]= (pt1->y * winy) + offsy;
				s1[0]= (pt2->x * winx) + offsx;		
				s1[1]= (pt2->y * winy) + offsy;
			}
			else {
				s0[0]= (pt1->x / 100 * winx);
				s0[1]= (pt1->y / 100 * winy);
				s1[0]= (pt2->x / 100 * winx);
				s1[1]= (pt2->y / 100 * winy);
			}		
			
			/* calculate gradient and normal - 'angle'=(ny/nx) */
			m1[1]= s1[1] - s0[1];		
			m1[0]= s1[0] - s0[0];
			Normalize2(m1);
			m2[1]= -m1[0];
			m2[0]= m1[1];
			
			/* always use pressure from first point here */
			pthick= (pt1->pressure * thickness);
			
			/* if the first segment, start of segment is segment's normal */
			if (i == 0) {
				/* draw start cap first 
				 *	- make points slightly closer to center (about halfway across) 
				 */				
				mt[0]= m2[0] * pthick * 0.5f;
				mt[1]= m2[1] * pthick * 0.5f;
				sc[0]= s0[0] - (m1[0] * pthick * 0.75f);
				sc[1]= s0[1] - (m1[1] * pthick * 0.75f);
				
				t0[0]= sc[0] - mt[0];
				t0[1]= sc[1] - mt[1];
				t1[0]= sc[0] + mt[0];
				t1[1]= sc[1] + mt[1];
				
				glVertex2fv(t0);
				glVertex2fv(t1);
				
				/* calculate points for start of segment */
				mt[0]= m2[0] * pthick;
				mt[1]= m2[1] * pthick;
				
				t0[0]= s0[0] - mt[0];
				t0[1]= s0[1] - mt[1];
				t1[0]= s0[0] + mt[0];
				t1[1]= s0[1] + mt[1];
				
				/* draw this line twice (first to finish off start cap, then for stroke) */
				glVertex2fv(t1);
				glVertex2fv(t0);
				glVertex2fv(t0);
				glVertex2fv(t1);
			}
			/* if not the first segment, use bisector of angle between segments */
			else {
				float mb[2]; 		/* bisector normal */
				float athick, dfac;		/* actual thickness, difference between thicknesses */
				
				/* calculate gradient of bisector (as average of normals) */
				mb[0]= (pm[0] + m2[0]) / 2;
				mb[1]= (pm[1] + m2[1]) / 2;
				Normalize2(mb);
				
				/* calculate gradient to apply 
				 * 	- as basis, use just pthick * bisector gradient
				 *	- if cross-section not as thick as it should be, add extra padding to fix it
				 */
				mt[0]= mb[0] * pthick;
				mt[1]= mb[1] * pthick;
				athick= Vec2Length(mt);
				dfac= pthick - (athick * 2);
				if ( ((athick * 2) < pthick) && (IS_EQ(athick, pthick)==0) ) 
				{
					mt[0] += (mb[0] * dfac);
					mt[1] += (mb[1] * dfac);
				}	
				
				/* calculate points for start of segment */
				t0[0]= s0[0] - mt[0];
				t0[1]= s0[1] - mt[1];
				t1[0]= s0[0] + mt[0];
				t1[1]= s0[1] + mt[1];
				
				/* draw this line twice (once for end of current segment, and once for start of next) */
				glVertex2fv(t1);
				glVertex2fv(t0);
				glVertex2fv(t0);
				glVertex2fv(t1);
			}
			
			/* if last segment, also draw end of segment (defined as segment's normal) */
			if (i == totpoints-2) {
				/* for once, we use second point's pressure (otherwise it won't be drawn) */
				pthick= (pt2->pressure * thickness);
				
				/* calculate points for end of segment */
				mt[0]= m2[0] * pthick;
				mt[1]= m2[1] * pthick;
				
				t0[0]= s1[0] - mt[0];
				t0[1]= s1[1] - mt[1];
				t1[0]= s1[0] + mt[0];
				t1[1]= s1[1] + mt[1];
				
				/* draw this line twice (once for end of stroke, and once for endcap)*/
				glVertex2fv(t1);
				glVertex2fv(t0);
				glVertex2fv(t0);
				glVertex2fv(t1);
				
				
				/* draw end cap as last step 
				 *	- make points slightly closer to center (about halfway across) 
				 */				
				mt[0]= m2[0] * pthick * 0.5f;
				mt[1]= m2[1] * pthick * 0.5f;
				sc[0]= s1[0] + (m1[0] * pthick * 0.75f);
				sc[1]= s1[1] + (m1[1] * pthick * 0.75f);
				
				t0[0]= sc[0] - mt[0];
				t0[1]= sc[1] - mt[1];
				t1[0]= sc[0] + mt[0];
				t1[1]= sc[1] + mt[1];
				
				glVertex2fv(t1);
				glVertex2fv(t0);
			}
			
			/* store stroke's 'natural' normal for next stroke to use */
			Vec2Copyf(pm, m2);
		}
		
		glEnd();
	}
	
	/* draw debug points of curve on top? (original stroke points) */
	if (debug) {
		bGPDspoint *pt;
		int i;
		
		glBegin(GL_POINTS);
		for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
			if (sflag & GP_STROKE_2DSPACE) {
				glVertex2f(pt->x, pt->y);
			}
			else if (sflag & GP_STROKE_2DIMAGE) {
				const float x= (float)((pt->x * winx) + offsx);
				const float y= (float)((pt->y * winy) + offsy);
				
				glVertex2f(x, y);
			}
			else {
				const float x= (float)(pt->x / 100 * winx);
				const float y= (float)(pt->y / 100 * winy);
				
				glVertex2f(x, y);
			}
		}
		glEnd();
	}
}
Esempio n. 4
0
static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFace *activetf)
{
	EditFace *efa;
	MTFace *tf;
	Image *ima= sima->image;
	float aspx, aspy, col[4], tf_uv[4][2];
	
	ED_space_image_uv_aspect(sima, &aspx, &aspy);
	
	switch(sima->dt_uvstretch) {
		case SI_UVDT_STRETCH_AREA:
		{
			float totarea=0.0f, totuvarea=0.0f, areadiff, uvarea, area;
			
			for(efa= em->faces.first; efa; efa= efa->next) {
				tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
				uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);

				totarea += EM_face_area(efa);
				//totuvarea += tf_area(tf, efa->v4!=0);
				totuvarea += uv_area(tf_uv, efa->v4!=0);
				
				if(uvedit_face_visible(scene, ima, efa, tf)) {
					efa->tmp.p = tf;
				}
				else {
					if(tf == activetf)
						activetf= NULL;
					efa->tmp.p = NULL;
				}
			}
			
			if(totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) {
				col[0] = 1.0;
				col[1] = col[2] = 0.0;
				glColor3fv(col);
				for(efa= em->faces.first; efa; efa= efa->next) {
					if((tf=(MTFace *)efa->tmp.p)) {
						glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
							glVertex2fv(tf->uv[0]);
							glVertex2fv(tf->uv[1]);
							glVertex2fv(tf->uv[2]);
							if(efa->v4) glVertex2fv(tf->uv[3]);
						glEnd();
					}
				}
			}
			else {
				for(efa= em->faces.first; efa; efa= efa->next) {
					if((tf=(MTFace *)efa->tmp.p)) {
						area = EM_face_area(efa) / totarea;
						uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
						//uvarea = tf_area(tf, efa->v4!=0) / totuvarea;
						uvarea = uv_area(tf_uv, efa->v4!=0) / totuvarea;
						
						if(area < FLT_EPSILON || uvarea < FLT_EPSILON)
							areadiff = 1.0;
						else if(area>uvarea)
							areadiff = 1.0-(uvarea/area);
						else
							areadiff = 1.0-(area/uvarea);
						
						weight_to_rgb(areadiff, col, col+1, col+2);
						glColor3fv(col);
						
						glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
							glVertex2fv(tf->uv[0]);
							glVertex2fv(tf->uv[1]);
							glVertex2fv(tf->uv[2]);
							if(efa->v4) glVertex2fv(tf->uv[3]);
						glEnd();
					}
				}
			}
			break;
		}
		case SI_UVDT_STRETCH_ANGLE:
		{
			float uvang1,uvang2,uvang3,uvang4;
			float ang1,ang2,ang3,ang4;
			float av1[3], av2[3], av3[3], av4[3]; /* use for 2d and 3d  angle vectors */
			float a;
			
			col[3] = 0.5; /* hard coded alpha, not that nice */
			
			glShadeModel(GL_SMOOTH);
			
			for(efa= em->faces.first; efa; efa= efa->next) {
				tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
				
				if(uvedit_face_visible(scene, ima, efa, tf)) {
					efa->tmp.p = tf;
					uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
					if(efa->v4) {
						
#if 0						/* Simple but slow, better reuse normalized vectors */
						uvang1 = RAD2DEG(Vec2Angle3(tf_uv[3], tf_uv[0], tf_uv[1]));
						ang1 = RAD2DEG(VecAngle3(efa->v4->co, efa->v1->co, efa->v2->co));
						
						uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2]));
						ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co));
						
						uvang3 = RAD2DEG(Vec2Angle3(tf_uv[1], tf_uv[2], tf_uv[3]));
						ang3 = RAD2DEG(VecAngle3(efa->v2->co, efa->v3->co, efa->v4->co));
						
						uvang4 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[3], tf_uv[0]));
						ang4 = RAD2DEG(VecAngle3(efa->v3->co, efa->v4->co, efa->v1->co));
#endif
						
						/* uv angles */
						VECSUB2D(av1, tf_uv[3], tf_uv[0]); Normalize2(av1);
						VECSUB2D(av2, tf_uv[0], tf_uv[1]); Normalize2(av2);
						VECSUB2D(av3, tf_uv[1], tf_uv[2]); Normalize2(av3);
						VECSUB2D(av4, tf_uv[2], tf_uv[3]); Normalize2(av4);
						
						/* This is the correct angle however we are only comparing angles
						 * uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90);*/
						uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI;
						uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI;
						uvang3 = NormalizedVecAngle2_2D(av3, av4)*180.0/M_PI;
						uvang4 = NormalizedVecAngle2_2D(av4, av1)*180.0/M_PI;
						
						/* 3d angles */
						VECSUB(av1, efa->v4->co, efa->v1->co); Normalize(av1);
						VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2);
						VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3);
						VECSUB(av4, efa->v3->co, efa->v4->co); Normalize(av4);
						
						/* This is the correct angle however we are only comparing angles
						 * ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90);*/
						ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI;
						ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI;
						ang3 = NormalizedVecAngle2(av3, av4)*180.0/M_PI;
						ang4 = NormalizedVecAngle2(av4, av1)*180.0/M_PI;
						
						glBegin(GL_QUADS);
						
						/* This simple makes the angles display worse then they really are ;)
						 * 1.0-pow((1.0-a), 2) */
						
						a = fabs(uvang1-ang1)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[0]);
						a = fabs(uvang2-ang2)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[1]);
						a = fabs(uvang3-ang3)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[2]);
						a = fabs(uvang4-ang4)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[3]);
						
					}
					else {
#if 0						/* Simple but slow, better reuse normalized vectors */
						uvang1 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[0], tf_uv[1]));
						ang1 = RAD2DEG(VecAngle3(efa->v3->co, efa->v1->co, efa->v2->co));
						
						uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2]));
						ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co));
						
						uvang3 = M_PI-(uvang1+uvang2);
						ang3 = M_PI-(ang1+ang2);
#endif						
						
						/* uv angles */
						VECSUB2D(av1, tf_uv[2], tf_uv[0]); Normalize2(av1);
						VECSUB2D(av2, tf_uv[0], tf_uv[1]); Normalize2(av2);
						VECSUB2D(av3, tf_uv[1], tf_uv[2]); Normalize2(av3);
						
						/* This is the correct angle however we are only comparing angles
						 * uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90); */
						uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI;
						uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI;
						uvang3 = NormalizedVecAngle2_2D(av3, av1)*180.0/M_PI;
						
						/* 3d angles */
						VECSUB(av1, efa->v3->co, efa->v1->co); Normalize(av1);
						VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2);
						VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3);
						/* This is the correct angle however we are only comparing angles
						 * ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90); */
						ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI;
						ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI;
						ang3 = NormalizedVecAngle2(av3, av1)*180.0/M_PI;
						
						/* This simple makes the angles display worse then they really are ;)
						 * 1.0-pow((1.0-a), 2) */
						
						glBegin(GL_TRIANGLES);
						a = fabs(uvang1-ang1)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[0]);
						a = fabs(uvang2-ang2)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[1]);
						a = fabs(uvang3-ang3)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[2]);
					}
					glEnd();
				}
				else {
					if(tf == activetf)
						activetf= NULL;
					efa->tmp.p = NULL;
				}
			}

			glShadeModel(GL_FLAT);
			break;
		}
	}
}