예제 #1
0
void QuadTree::CheckWalls( Plane pl0, Plane pl1, Plane pl2, Plane pl3, Ball* b , Spinner* s )
{
	//planes 0 1 2 3
	//is behind bools!
	bool p0 = false;
	bool p1 = false;
	bool p2 = false;
	bool p3 = false;
	Vector3 p0diff,p1diff,p2diff,p3diff;

	p0diff = pl0.ClosestPointToPoint(b->Position()) - b->Position();
	if(p0diff.getLength() <= b->radius)
	{
		p0 = true;
	}
	p1diff = pl1.ClosestPointToPoint(b->Position()) - b->Position();
	if(p1diff.getLength() <= b->radius)
	{
		p1 = true;
	}
	p2diff = pl2.ClosestPointToPoint(b->Position()) - b->Position();
	if(p2diff.getLength() <= b->radius)
	{
		p2 = true;
	}
	p3diff = pl3.ClosestPointToPoint(b->Position()) - b->Position();
	if(p3diff.getLength() <= b->radius)
	{
		p3 = true;
	}

	// Check for which plane(s) it HAS collided with
	if (p0)
	{
		HitSpinnerWall(s, pl0, b);
	}
	if (p1)
	{
		HitSpinnerWall(s, pl1, b);
	}
	if (p2)
	{
		HitSpinnerWall(s, pl2, b);
	}
	if (p3)
	{
		HitSpinnerWall(s, pl3, b);
	}
}
예제 #2
0
void HitSpinnerWall( Spinner* sp, Plane &plane, Ball* b )
{
	
	Vector3 wall = plane.points[2] - plane.points[0];
	Vector3 ballFromWall = b->Position() - plane.points[0];

	float relativePosition = plane.normal * ballFromWall;
	float relativeDirection = plane.normal * b->Velocity();
	if ((relativePosition > 0 && relativeDirection < 0) || (relativePosition < 0 && relativeDirection > 0))
	{
		float theta, c, s;
		theta = acos((wall * Vector3(1,0,0))/wall.getLength());
		if (b->position.x<0)
		{
			theta *= -1;
		}
		c = cos(theta), s = sin(theta);

		Vector3 position2 = Vector3();
		Vector3 velocityRot = Vector3();

		position2 = Vector3(c * ballFromWall.x + s * ballFromWall.y, c * ballFromWall.y - s * ballFromWall.x, 0);
		velocityRot = Vector3( c * b->Velocity().x + s * b->Velocity().y, c * b->Velocity().y - s * b->Velocity().x, 0);

		// Set the ball outside the wall, reverse velocity toward wall
		Vector3 scaledNormal = b->radius * Vector3(0,-1,0);
		position2.y = scaledNormal.y;
		velocityRot.y *= -1;

		// Rotate back
		ballFromWall = Vector3(c * position2.x - s * position2.y,c * position2.y + s * position2.x,0);
		b->Velocity(Vector3(c * velocityRot.x - s * velocityRot.y,c * velocityRot.y + s * velocityRot.x,0));

		Point3 newPos = plane.points[0] + ballFromWall;
		b->position = newPos;

		//float bEnergy = .5 * b->Mass() * b->Velocity() * b->Velocity();
		Vector3 momenteum = b->Mass() * b->Velocity();

		Point3 closest = plane.ClosestPointToPoint(b->Position());
		//Vector3 tempV = diff;
		//tempV.normalize();
		//Vector3 proj = (closest*tempV)*tempV;
		//float temp = proj.getLength();
		//// check if in the bounding box
		//if(diff.getLength() > temp + b->radius)
		//{
		//	continue;
		//}
		//// then it needs to go, "Hey!".


		////find the force applied to the bar
		// ft = dp/dt = m*dv/dt
		////find perpendicular momentum
		//Vector3 totalForce = bEnergy * b->Velocity();

		//// t = r X F
		//Vector3 torque = diff.cross(totalForce);
		Vector3 radius = Point3(closest.x,closest.y,closest.z) - sp->Position();
		Vector3 torque = radius.cross(momenteum);
		
		Vector3 dL = .05 * torque;

		//// find the rotation matrix and the inverse of the rotation matrix
		Matrix33 myRotation = Matrix33(sp->Rotation());
		Matrix33 myRotationT = myRotation.Transpose();

		sp->MyL(sp->MyL() + dL);

		////w(i+1) = q(i+1) * I(-1) * qT(i+1) * L(i+1)
		sp->AngularVel(myRotation * *sp->Tensor()->inverse() * myRotationT * sp->MyL());

		////q(n+1) = q(n) + h(.5 * w(n)*q(n))
		sp->Rotation(sp->Rotation() + .05f*(.5 * Quaternion(sp->AngularVel()) * sp->Rotation()));
		Quaternion q = sp->Rotation();
		q.normalize();
		sp->Rotation(q);
	}
}