コード例 #1
0
ファイル: bezier.cpp プロジェクト: Timo6/trackeditor
bool BEZIER::Collide(VERTEX origin, VERTEX direction, VERTEX &outtri)
{
	int i;
	
	VERTEX curtri[3];
	
	int retval = 0;
	
	float t, u, v;
	
	int x, y;
	
	for (i = 0; i < NumTris(COLLISION_DIVS) && !retval; i++)
	{	
		GetTri(COLLISION_DIVS, i, curtri);
		
		retval = INTERSECT_FUNCTION(origin.v3(), direction.v3(),
			curtri[0].v3(), curtri[1].v3(), curtri[2].v3(), 
			&t, &u, &v);
		
		if (retval)
		{
			if (i % 2 == 0)
			{
				u = 1.0 - u;
				v = 1.0 - v;
			}
			
			u = 1.0 - u;
			v = 1.0 - v;
			
			x = (i/2) % COLLISION_DIVS;
			y = (i/2) / COLLISION_DIVS;
			u += (float) x;
			v += (float) y;
			u = u / (float) COLLISION_DIVS;
			v = v / (float) COLLISION_DIVS;
			
			//u = 1.0 - u;
			//v = 1.0 - v;
			
			//cout << u << "," << v << endl;
			outtri = SurfCoord(u, v);
			return true;
		}
	}
	
	outtri = origin;
	return false;
}
コード例 #2
0
ファイル: bezier.cpp プロジェクト: Timo6/trackeditor
void BEZIER::GetTri(int div, int num, VERTEX outtri[3])
{
	int firsttri = num % 2;
	
	int x = (num/2) % div;
	int y = (num/2) / div;

	if (firsttri == 0)
	{		
		float px = (float) x / (float) div;
		float py = (float) y / (float) div;
		float pxo = (float) (x+1) / (float) div;
		float pyo = (float) (y+1) / (float) div;
	
		/*glVertex3fv(SurfCoord(px, py).v3());
		glVertex3fv(SurfCoord(pxo, py).v3());
		glVertex3fv(SurfCoord(pxo, pyo).v3());*/
		
		outtri[0] = SurfCoord(px, py);
		outtri[1] = SurfCoord(pxo, py);
		outtri[2] = SurfCoord(px, pyo);
	}
	else
	{
		float px = (float) x / (float) div;
		float py = (float) y / (float) div;
		float pxo = (float) (x+1) / (float) div;
		float pyo = (float) (y+1) / (float) div;
		
		/*glVertex3fv(SurfCoord(px, py).v3());
		glVertex3fv(SurfCoord(pxo, pyo).v3());
		glVertex3fv(SurfCoord(px, pyo).v3());*/
		
		outtri[0] = SurfCoord(pxo, pyo);
		outtri[1] = SurfCoord(px, pyo);
		outtri[2] = SurfCoord(pxo, py);
	}
}
コード例 #3
0
ファイル: bezier.cpp プロジェクト: Alexander-Eck/vdrift
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;
}
コード例 #4
0
ファイル: bezier.cpp プロジェクト: Alexander-Eck/vdrift
void Bezier::Attach(Bezier & other, bool reverse)
{
	/*if (!reverse)
	{
		//move the other patch to the location of this patch and force its
		// intermediate points into a nice grid layout
		other.SetFromCorners(other.points[0][0], other.points[0][3], points[0][0], points[0][3]);

		for (int x = 0; x < 4; x++)
		{
			//slope points in the forward direction
			Vec3 slope = other.points[0][x] - points[3][x];
			if (slope.Magnitude() > 0.0001)
				slope = slope.Normalize();

			float otherlen = (other.points[0][x] - other.points[3][x]).Magnitude();
			float mylen = (points[0][x] - points[3][x]).Magnitude();

			float meanlen = (otherlen + mylen)/2.0;
			float leglen = meanlen / 3.0;

			if (slope.Magnitude() > 0.0001)
			{
				other.points[2][x] = other.points[3][x] + slope*leglen;
				points[1][x] = points[0][x] + slope*(-leglen);
			}
			else
			{
				other.points[2][x] = other.points[3][x];
				points[1][x] = points[0][x];
			}
		}
	}*/

	//CheckForProblems();

	//store the pointer to next patch
	next_patch = &other;

	//calculate the track radius at the connection of this patch and next patch
	Vec3 a = SurfCoord(0.5,0.0);
	Vec3 b = SurfCoord(0.5,1.0);
	Vec3 c = other.SurfCoord(0.5,1.0);

	if (reverse)
	{
		a = SurfCoord(0.5,1.0);
		b = SurfCoord(0.5,0.0);
		c = other.SurfCoord(0.5,0.0);

		//Reverse();
	}

	//racing_line = a;
	Vec3 d1 = a - b;
	Vec3 d2 = c - b;
	float diff = d2.Magnitude() - d1.Magnitude();
	double dd = ((d1.Magnitude() < 0.0001) || (d2.Magnitude() < 0.0001)) ? 0.0 : d1.Normalize().dot(d2.Normalize());
	float angle = acos((dd>=1.0L)?1.0L:(dd<=-1.0L)?-1.0L:dd);
	float d1d2mag = d1.Magnitude() + d2.Magnitude();
	float alpha = (d1d2mag < 0.0001) ? 0.0f : (M_PI * diff + 2.0 * d1.Magnitude() * angle) / d1d2mag / 2.0;
	if (fabs(alpha - M_PI/2.0) < 0.001) track_radius = 10000.0;
	else track_radius = d1.Magnitude() / 2.0 / cos(alpha);
	if (d1.Magnitude() < 0.0001)
		track_curvature = 0.0;
	else
		track_curvature = 2.0 * cos(alpha) / d1.Magnitude();

	//determine it's a left or right turn at the connection
	Vec3 d = d1.cross(d2);
	if (fabs(d[0]) < 0.1 && fabs(d[1]) < 0.1 && fabs(d[2]) < 0.1)
	{
		turn = 0; //straight ahead
	}
	else if (d[1] > 0.0) turn = -1; //left turn ahead
	else turn = 1; //right turn ahead

	//calculate distance from start of the road
	if (other.next_patch == NULL || reverse) other.dist_from_start = dist_from_start + d1.Magnitude();
	length = d1.Magnitude();
}
コード例 #5
0
ファイル: bezier.cpp プロジェクト: ddxxpp/stuntrally
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;
	}
}
コード例 #6
0
ファイル: bezier.cpp プロジェクト: Timo6/trackeditor
void BEZIER::DrawSurf(int div, float trans)
{
	int x, y;
	
	float px, py, pxo, pyo, col;
	
	//VERTEX temp[4];
	VERTEX normal;
	
	if (div < 1)
		div = 1;
	
	glBegin(GL_TRIANGLES);
	
	for (x = 0; x < div; x++)
	{
		for (y = 0; y < div; y++)
		{
			//if (x < div - 1 && y < div - 1)
			{
				px = (float) x / (float) div;
				py = (float) y / (float) div;
				pxo = (float) (x+1) / (float) div;
				pyo = (float) (y+1) / (float) div;
				
				normal = (SurfCoord(pxo, pyo) - SurfCoord(px, py)).cross(SurfCoord(pxo, py) - SurfCoord(px, py));
				normal = normal.normalize();
				col = normal.y;
				col = col * col;
				glColor4f(col,col,col, trans);
				
				glVertex3fv(SurfCoord(pxo, py).v3());
				glVertex3fv(SurfCoord(px, py).v3());
				glVertex3fv(SurfCoord(px, pyo).v3());
				
				normal = (SurfCoord(px, pyo) - SurfCoord(px, py)).cross(SurfCoord(pxo, pyo) - SurfCoord(px, py));
				normal = normal.normalize();
				col = normal.y;
				col = col * col;
				glColor4f(col,col,col, trans);
				
				glVertex3fv(SurfCoord(px, pyo).v3());
				glVertex3fv(SurfCoord(pxo, pyo).v3());
				glVertex3fv(SurfCoord(pxo, py).v3());
			}
		}
	}

	glEnd();
}