コード例 #1
0
// Precalculations for intersection testing speed
void ViewableParallelogram::PreCalcInfo()
{
	VectorR3 EdgeAB = VertexB - VertexA;
	VectorR3 EdgeBC = VertexC - VertexB;
	LengthAB = EdgeAB.Norm();
	LengthBC = EdgeBC.Norm();

	VertexD = VertexA;
	VertexD += EdgeBC;			// The fourth vertex

	EdgeAB /= LengthAB;					// Normalize
	EdgeBC /= LengthBC;					// Normalize

	Normal = EdgeAB*EdgeBC;
	double mag = Normal.Norm();
	if ( mag>0.0 && LengthAB>0.0 && LengthBC>0.0 ) {
		Normal /= mag;				// Unit Vector to parallelogram
	}
	else {
		Normal.SetZero();			// In this case, the parallelogram is malformed.
	}
	PlaneCoef = VertexB^Normal;

	NormalAB = Normal*EdgeAB;		// Normal in from edge AB
	NormalBC = Normal*EdgeBC;		// Normal in from edge BC
	NormalAB.ReNormalize();			// Just in case
	NormalBC.ReNormalize();

	CoefAB = VertexA^NormalAB;		// Coef. for edge AB.
	CoefBC = VertexB^NormalBC;
	CoefCD = VertexC^NormalAB;
	CoefDA = VertexA^NormalBC;
}			
コード例 #2
0
ファイル: LinearR3.cpp プロジェクト: Hongtae/bullet3
// RotateToMap returns a rotation map which rotates fromVec to have the
//		same direction as toVec.
// fromVec and toVec should be unit vectors
RotationMapR3 RotateToMap(const VectorR3& fromVec, const VectorR3& toVec)
{
	VectorR3 crossVec = fromVec;
	crossVec *= toVec;
	double sintheta = crossVec.Norm();
	double costheta = fromVec ^ toVec;
	if (sintheta <= 1.0e-40)
	{
		if (costheta > 0.0)
		{
			return (RotationMapR3(
				1.0, 0.0, 0.0,
				0.0, 1.0, 0.0,
				0.0, 0.0, 1.0));
		}
		else
		{
			GetOrtho(toVec, crossVec);  // Get arbitrary orthonormal vector
			return (VrRotate(costheta, sintheta, crossVec));
		}
	}
	else
	{
		crossVec /= sintheta;  // Normalize the vector
		return (VrRotate(costheta, sintheta, crossVec));
	}
}
コード例 #3
0
ファイル: LinearR3.cpp プロジェクト: AndrewMeadows/bullet3
RotationMapR3 VrRotateAlign( const VectorR3& fromVec, const VectorR3& toVec)
{
	VectorR3 crossVec = fromVec;
	crossVec *= toVec;
	double sinetheta = crossVec.Norm();	// Not yet normalized!
	if ( sinetheta < 1.0e-40 ) {
		return ( RotationMapR3( 
					1.0, 0.0, 0.0, 
					0.0, 1.0, 0.0, 
					0.0, 0.0, 1.0) );
	}
	crossVec /= sinetheta;				// Normalize the vector
	double scale = 1.0/sqrt(fromVec.NormSq()*toVec.NormSq());
	sinetheta *= scale;
	double cosinetheta = (fromVec^toVec)*scale;
	return ( VrRotate( cosinetheta, sinetheta, crossVec) );
}
コード例 #4
0
ファイル: LoadNffFile.cpp プロジェクト: Hengplank/kucgbowling
void NffFileLoader::ProcessConeCylNFF( const VectorR3& baseCenter, double baseRadius, 
							const VectorR3& topCenter, double topRadius )
{
	bool isCone = (topRadius==0.0);
	if ( !isCone && topRadius!=baseRadius ) {
		UnsupportedTruncatedCone();
		if ( topRadius<0.5*baseRadius ) {
			isCone = true;				// Render as a true code
		}
		else {
			topRadius = baseRadius;   // Render as a cylinder
		}
	}
	VectorR3 centerLine = topCenter;
	centerLine -= baseCenter;
	double height = centerLine.Norm();
	if ( height==0.0 ) {
		return;				// We do not support zero height cylinders (Nor does NFF!)
	}
	centerLine /= height;	// Normalize
	if ( isCone ) {
		ViewableCone* vc = new ViewableCone();
		vc->SetApex(topCenter);
		vc->SetCenterAxis(centerLine);
		vc->SetSlope( baseRadius/height );
		vc->SetHeight( height );
 		ScenePtr->AddViewable(vc);
   }
	else {	
		// Create a cylinder
		ViewableCylinder* vc = new ViewableCylinder();
		vc->SetCenterAxis(centerLine);
		centerLine = topCenter;
		centerLine += baseCenter;
		centerLine *= 0.5;
		vc->SetCenter( centerLine );
		vc->SetRadius( baseRadius );
		vc->SetHeight( height );
		ScenePtr->AddViewable(vc);
	}
}
コード例 #5
0
bool ViewableTorus::FindIntersectionNT ( 
				const VectorR3& viewPos, const VectorR3& viewDir, 
				double maxDistance, double *intersectDistance, 
				VisiblePoint& returnedPoint ) const
{

	// Precheck for collisions by
	//	checking if passes to within a bounding box

	bool insideFlag = true;		// Whether viewPos is inside bounding box
	double minDistBack = DBL_MAX;	// min. distance to a backplane bounding the box
	double maxDistFront= -DBL_MAX;	// mix. distance to a frontplane bounding the box

	double pdotn;
	double alpha;
	pdotn = (viewPos^AxisC) - CenterCoefC;
	alpha = viewDir^AxisC;
	if ( !CollideTwoPlanes(pdotn, alpha, MinorRadius, 
							&insideFlag, &minDistBack, &maxDistFront) ) {
		return false;
	}
	pdotn = (viewPos^AxisA) - CenterCoefA;
	alpha = viewDir^AxisA;
	if ( !CollideTwoPlanes(pdotn, alpha, OuterRadius, 
							&insideFlag, &minDistBack, &maxDistFront) ) {
		return false;
	}
	pdotn = (viewPos^AxisB) - CenterCoefB;
	alpha = viewDir^AxisB;
	if ( !CollideTwoPlanes(pdotn, alpha, OuterRadius, 
							&insideFlag, &minDistBack, &maxDistFront) ) {
		return false;
	}

	assert ( minDistBack>=maxDistFront );
	assert ( insideFlag || maxDistFront>=0.0 );
	assert ( maxDistFront < 1000.0 );
	if (maxDistFront>maxDistance) {
		return false;
	}

	// Bounding box precheck is done. Now do the actual intersection test.

	// Set up the degree 4 polynomial for the torus intersection
	// Coefficients are:
	//	A = 1
	//	B = 4 u \cdot p
	//	C = 4(u\cdot p)^2 + 2(p\cdot p) - 2(M^2+m^2) + 4M^2(u_C \cdot u)
	//	D = 4[(p \cdot p)(u \cdot p) - (M^2+m^2)(u \cdot p) + 2M^2(u_C \dot p)^2]
	//	E = ((p \cdot p)^2 - 2(M^2+m^2)(p \cdot p) + 4M^2(u_C\cdot p)^2 +(M^2-m^2)^2

	double moveFwdDist = Max(0.0,maxDistFront);

	double coefs[5];
	double roots[4];
	double &A=coefs[0], &B=coefs[1], &C=coefs[2], &D=coefs[3], &E=coefs[4];

	A = 1;
	VectorR3 viewPosRel;
	viewPosRel = viewDir;
	viewPosRel *= moveFwdDist;	// Move forward distance moveFwdDist
	viewPosRel += viewPos;
	viewPosRel -= Center;		// Position relative to center
	double udotp = (viewDir^viewPosRel);
	B = 4.0*udotp;
	double MSq = Square(MajorRadius);
	double mSq = Square(MinorRadius);
	double RadiiSqSum = MSq + mSq;
	double ucdotp = (AxisC^viewPosRel);
	double ucdotu = (AxisC^viewDir);
	double pSq = (viewPosRel^viewPosRel);
	C = 4.0*udotp*udotp + 2.0*pSq - 2.0*RadiiSqSum + 4.0*MSq*ucdotu*ucdotu;
	D = 4.0 * ( (pSq-RadiiSqSum)*udotp + 2.0*MSq*ucdotp*ucdotu );
	E = (pSq - 2.0*RadiiSqSum)*pSq + 4.0*MSq*ucdotp*ucdotp + Square(MSq-mSq);

	int numRoots = PolySolveReal( 4, coefs, roots );
	for ( int i=0; i<numRoots; i++ ) {
		roots[i] += moveFwdDist;		// Restate as distance from viewPos
		if ( roots[i] >= maxDistance ) {
			return false;
		}
		if ( roots[i]>0.0 ) {
			// Return this visible point
			*intersectDistance = roots[i];
			VectorR3 Point = viewDir;
			Point *= roots[i];
			Point += viewPos;
			returnedPoint.SetPosition(Point);  // Intersection position (not relative to center)

			if ( i & 0x01 ) {
				returnedPoint.SetBackFace();					// Orientation
				returnedPoint.SetMaterial( *InnerMaterial );	// Material
			}
			else {
				returnedPoint.SetFrontFace();					// Orientation
				returnedPoint.SetMaterial( *OuterMaterial );	// Material
			}

			// Outward normal
			Point -= Center;			// Now its the relative point
			double xCoord = Point^AxisA;	// forward axis
			double yCoord = Point^AxisB;	// rightward axis
			double zCoord = Point^AxisC;	// upward axis
			VectorR3 outN = AxisC;
			outN *= -zCoord;
			outN += Point;						// Project point down to plane of torus center
			double outNnorm = outN.Norm();
			outN *= MajorRadius/(-outNnorm);	// Negative point projected to center path of torus
			outN += Point;						// Displacement of point from center path of torus
			outN /= MinorRadius;				// Should be outward unit vector
			outN.ReNormalize();					// Fix roundoff error problems
			returnedPoint.SetNormal(outN);		// Outward normal

			// u - v coordinates
			double u = atan2( yCoord, xCoord );
			u = u*PI2inv+0.5;
			double bVal = outNnorm-MajorRadius;
			double v = atan2( zCoord, bVal );
			v = v*PI2inv+0.5;
			returnedPoint.SetUV(u , v);
			returnedPoint.SetFaceNumber( 0 );

			return true;
		}
	}
	return false;
}