Ejemplo n.º 1
0
bool Bezier::CollideSubDivQuadSimpleNorm(const Vec3 & origin, const Vec3 & direction, Vec3 &outtri, Vec3 & normal) const
{
	bool col = false;
	const int COLLISION_QUAD_DIVS = 6;
	const float areacut = 0.5;

	float t, u, v;

	float su = 0;
	float sv = 0;

	float umin = 0;
	float umax = 1;
	float vmin = 0;
	float vmax = 1;

	Vec3 ul = points[3][3];
	Vec3 ur = points[3][0];
	Vec3 br = points[0][0];
	Vec3 bl = points[0][3];

	for (int i = 0; i < COLLISION_QUAD_DIVS; i++)
	{
		float tu[2];
		float tv[2];

		//speedup for i == 0
		//if (i != 0)
		{
			tu[0] = umin;
			if (tu[0] < 0)
				tu[0] = 0;
			tu[1] = umax;
			if (tu[1] > 1)
				tu[1] = 1;

			tv[0] = vmin;
			if (tv[0] < 0)
				tv[0] = 0;
			tv[1] = vmax;

			if (tv[1] > 1)
				tv[1] = 1;

			ul = SurfCoord(tu[0], tv[0]);
			ur = SurfCoord(tu[1], tv[0]);
			br = SurfCoord(tu[1], tv[1]);
			bl = SurfCoord(tu[0], tv[1]);
		}

		col = IntersectQuadrilateralF(origin, direction, ul, ur, br, bl, t, u, v);

		if (col)
		{
			//expand quad UV to surface UV
			//su = u * (umax - umin) + umin;
			//sv = v * (vmax - vmin) + vmin;

			su = u * (tu[1] - tu[0]) + tu[0];
			sv = v * (tv[1] - tv[0]) + tv[0];

			//place max and min according to area hit
			vmax = sv + (0.5*areacut)*(vmax - vmin);
			vmin = sv - (0.5*areacut)*(vmax - vmin);
			umax = su + (0.5*areacut)*(umax - umin);
			umin = su - (0.5*areacut)*(umax - umin);
		}
		else
		{
			outtri = origin;
			return false;
		}
	}

	outtri = SurfCoord(su, sv);
	normal = SurfNorm(su, sv);
	return true;
}
Ejemplo n.º 2
0
bool BEZIER::CollideSubDivQuadSimpleNorm(const MATHVECTOR<float,3> & origin, const MATHVECTOR<float,3> & direction, MATHVECTOR<float,3> &outtri, MATHVECTOR<float,3> & normal) const
{
	bool col = false;
	const int COLLISION_QUAD_DIVS = 6;
	const bool QUAD_DIV_FAST_DISCARD = true;
	
	float t, u, v;
	
	float su = 0;
	float sv = 0;
	
	float umin = 0;
	float umax = 1;
	float vmin = 0;
	float vmax = 1;
	
	//const float fuzziness = 0.13;
	
	MATHVECTOR<float,3> ul = points[3][3];
	MATHVECTOR<float,3> ur = points[3][0];
	MATHVECTOR<float,3> br = points[0][0];
	MATHVECTOR<float,3> bl = points[0][3];
	
	//int subdivnum = 0;

	bool loop = true;
	
	float areacut = 0.5;

	for (int i = 0; i < COLLISION_QUAD_DIVS && loop; i++)
	{
		float tu[2];
		float tv[2];
		
		//speedup for i == 0
		//if (i != 0)
		{
			tu[0] = umin;
			if (tu[0] < 0)
				tu[0] = 0;
			tu[1] = umax;
			if (tu[1] > 1)
				tu[1] = 1;
			
			tv[0] = vmin;
			if (tv[0] < 0)
				tv[0] = 0;
			tv[1] = vmax;
			
			if (tv[1] > 1)
				tv[1] = 1;
			
			ul = SurfCoord(tu[0], tv[0]);
			ur = SurfCoord(tu[1], tv[0]);
			br = SurfCoord(tu[1], tv[1]);
			bl = SurfCoord(tu[0], tv[1]);
		}
		
		//u = v = 0.0;

		col = IntersectQuadrilateralF(origin, direction,
			ul, ur, br, bl,
			t, u, v);
		
		if (col)
		{
			//expand quad UV to surface UV
			//su = u * (umax - umin) + umin;
			//sv = v * (vmax - vmin) + vmin;
			
			su = u * (tu[1] - tu[0]) + tu[0];
			sv = v * (tv[1] - tv[0]) + tv[0];
			
			//place max and min according to area hit
			vmax = sv + (0.5*areacut)*(vmax-vmin);
			vmin = sv - (0.5*areacut)*(vmax-vmin);
			umax = su + (0.5*areacut)*(umax-umin);
			umin = su - (0.5*areacut)*(umax-umin);
		}
		else
		{
			if ((i == 0) && QUAD_DIV_FAST_DISCARD)
			//if (QUAD_DIV_FAST_DISCARD)
			{
				outtri = origin;
				return false;
			}
			else
			{
				/*if (verbose)
				{
					cout << "<" << i << ": nocol " << su << "," << sv << ">" << endl;
					cout << "<" << umin << "," << umax << ";" << vmin << "," << vmax << ">" << endl;
					
					ul.DebugPrint();
					ur.DebugPrint();
					bl.DebugPrint();
					br.DebugPrint();
					
					cout << endl;
				}*/
				
				loop = false;
			}
		}
	}
	
	if (col)// || QUAD_DIV_FAST_DISCARD)
	//if (col)
	{
		/*if (!col)
			cout << "blip " << su << "," << sv << ": " << u << "," << v << endl;*/
		outtri = SurfCoord(su, sv);
		normal = SurfNorm(su, sv);
		//if (verbose)
			//cout << "<" << i << ">" << endl;
		return true;
	}
	else
	{
		outtri = origin;
		return false;
	}
}