public Bumper(Vector3 position, Vector3 rotation, float scale, GraphicsDevice device) : base(position, rotation, scale, device) { surfaces = new Plane[10]; Vector3 frontPosition = new Vector3(position.X, position.Y - 1f * scale, position.Z + 1f * scale); Vector3 frontRotation = new Vector3(rotation.X + (float)(0.5f * Math.PI), rotation.Y, rotation.Z); surfaces[0] = new Plane(frontPosition, frontRotation, scale, device); surfaces[1] = new Plane(new Vector3(frontPosition.X, frontPosition.Y + 2f * scale, frontPosition.Z), frontRotation, scale, device); Vector3 leftPosition = new Vector3(position.X - 1f * scale, position.Y - 1f * scale, position.Z); Vector3 leftRotation = new Vector3(rotation.X, rotation.Y, rotation.Z + (float)(0.5f * Math.PI)); surfaces[2] = new Plane(leftPosition, leftRotation, scale, device); surfaces[3] = new Plane(new Vector3(leftPosition.X, leftPosition.Y + 2f * scale, leftPosition.Z), leftRotation, scale, device); Vector3 rightPosition = new Vector3(position.X + 1f * scale, position.Y - 1f * scale, position.Z); Vector3 rightRotation = new Vector3(rotation.X, rotation.Y, rotation.Z + (float)(1.5f * Math.PI)); surfaces[4] = new Plane(rightPosition, rightRotation, scale, device); surfaces[5] = new Plane(new Vector3(rightPosition.X, rightPosition.Y + 2f * scale, rightPosition.Z), rightRotation, scale, device); Vector3 backPosition = new Vector3(position.X, position.Y - 1f * scale, position.Z - 1f * scale); Vector3 backRotation = new Vector3(rotation.X + (float)(1.5f * Math.PI), rotation.Y, rotation.Z); surfaces[6] = new Plane(backPosition, backRotation, scale, device); surfaces[7] = new Plane(new Vector3(backPosition.X, backPosition.Y + 2f * scale, backPosition.Z), backRotation, scale, device); Vector3 topPosition = new Vector3(position.X, position.Y + 2f * scale, position.Z); Vector3 topRotation = rotation; surfaces[8] = new Plane(topPosition, topRotation, scale, device); Vector3 bottomPosition = new Vector3(position.X, position.Y - 2f * scale, position.Z); Vector3 bottomRotation = new Vector3(rotation.X, rotation.Y, rotation.Z + (float)(1f * Math.PI)); surfaces[9] = new Plane(bottomPosition, bottomRotation, scale, device); }
public Box(Vector3 position, Vector3 rotation, float scale, GraphicsDevice device) : base() { surfaces = new Plane[13]; //A bottom plane with hole float tild = (float)(0.01 * Math.PI); Vector3 leftTilted = new Vector3(rotation.X, rotation.Y, rotation.Z + tild); Vector3 rightTilted = new Vector3(rotation.X, rotation.Y, rotation.Z - tild); float tildHeightOffSet = (float)Math.Sin(tild)*scale; Vector3 botPosition1 = new Vector3(position.X + 2f / 3f * scale, position.Y - scale + tildHeightOffSet/3, position.Z - 2f / 3f * scale); surfaces[0] = new Plane(botPosition1, leftTilted, scale / 3f, device); Vector3 botPosition2 = new Vector3(position.X + 2f / 3f * scale, position.Y - scale + tildHeightOffSet / 3, position.Z); surfaces[1] = new Plane(botPosition2, leftTilted, scale / 3f, device); Vector3 botPosition3 = new Vector3(position.X + 2f / 3f * scale, position.Y - scale + tildHeightOffSet / 3, position.Z + 2f / 3f * scale); surfaces[2] = new Plane(botPosition3, leftTilted, scale / 3f, device); Vector3 botPosition4 = new Vector3(position.X, position.Y - scale, position.Z); surfaces[3] = new Plane(botPosition4, rotation, scale / 3f, device); Vector3 botPosition5 = new Vector3(position.X - 2f / 3f * scale, position.Y - scale + tildHeightOffSet / 3, position.Z + 2f / 3f * scale); surfaces[4] = new Plane(botPosition5, rightTilted, scale / 3f, device); Vector3 botPosition6 = new Vector3(position.X - 2f / 3f * scale, position.Y - scale + tildHeightOffSet / 3, position.Z); surfaces[5] = new Plane(botPosition6, rightTilted, scale / 3f, device); Vector3 botPosition7 = new Vector3(position.X - 2f / 3f * scale, position.Y - scale + tildHeightOffSet / 3, position.Z - 2f / 3f * scale); surfaces[6] = new Plane(botPosition7, rightTilted, scale / 3f, device); Vector3 botPosition8 = new Vector3(position.X, position.Y - scale, position.Z - 2f / 3f * scale); surfaces[7] = new Plane(botPosition8, rotation, scale / 3f, device); //The box Vector3 topPosition = new Vector3(position.X, position.Y + scale, position.Z); Vector3 topRotation = new Vector3(rotation.X + (float)Math.PI, rotation.Y, rotation.Z); surfaces[8] = new Plane(topPosition, topRotation, scale, device); Vector3 rightPosition = new Vector3(position.X + scale, position.Y, position.Z); Vector3 rightRotation = new Vector3(rotation.X, rotation.Y, rotation.Z + (float)(0.5 * Math.PI)); surfaces[9] = new Plane(rightPosition, rightRotation, scale, device); Vector3 leftPosition = new Vector3(position.X - scale, position.Y, position.Z); Vector3 leftRotation = new Vector3(rotation.X, rotation.Y, rotation.Z + (float)(1.5 * Math.PI)); surfaces[10] = new Plane(leftPosition, leftRotation, scale, device); Vector3 backPosition = new Vector3(position.X, position.Y, position.Z + scale); Vector3 backRotation = new Vector3(rotation.X + (float)(1.5 * Math.PI), rotation.Y, rotation.Z); surfaces[11] = new Plane(backPosition, backRotation, scale, device); Vector3 frontPosition = new Vector3(position.X, position.Y, position.Z - scale); Vector3 frontRotation = new Vector3(rotation.X + (float)(0.5 * Math.PI), rotation.Y, rotation.Z); surfaces[12] = new Plane(frontPosition, frontRotation, scale, device); }
public Flipper(Vector3 position, Vector3 pivot, float maxAngle, float rotationASecond, Vector3 rotation, float scale, Ball ball, GraphicsDevice device) : base() { this.pivot = position + pivot * scale; this.rotation = 0; this.maxAngle = maxAngle; this.rotationASecond = rotationASecond; this.ball = ball; surfaces = new Plane[10]; //The box Vector3 botPosition = new Vector3(position.X, position.Y - scale, position.Z); Vector3 botRotation = new Vector3(rotation.X + (float)Math.PI, rotation.Y, rotation.Z); surfaces[0] = new Plane(botPosition, botRotation, scale, device); Vector3 botPosition2 = new Vector3(position.X + 2 * scale, position.Y - scale, position.Z); surfaces[1] = new Plane(botPosition2, botRotation, scale, device); Vector3 topPosition = new Vector3(position.X, position.Y + scale, position.Z); Vector3 topRotation = rotation; surfaces[2] = new Plane(topPosition, topRotation, scale, device); Vector3 topPosition2 = new Vector3(position.X + 2 * scale, position.Y + scale, position.Z); surfaces[3] = new Plane(topPosition2, topRotation, scale, device); Vector3 rightPosition = new Vector3(position.X + 3 * scale, position.Y, position.Z); Vector3 rightRotation = new Vector3(rotation.X, rotation.Y, rotation.Z - 0.5f*(float)Math.PI); surfaces[4] = new Plane(rightPosition, rightRotation, scale, device); Vector3 leftPosition = new Vector3(position.X - scale, position.Y, position.Z); Vector3 leftRotation = new Vector3(rotation.X, rotation.Y, rotation.Z + 0.5f * (float)Math.PI); surfaces[5] = new Plane(leftPosition, leftRotation, scale, device); Vector3 backPosition = new Vector3(position.X, position.Y, position.Z + scale); Vector3 backRotation = new Vector3(rotation.X + 0.5f * (float)Math.PI, rotation.Y, rotation.Z); surfaces[6] = new Plane(backPosition, backRotation, scale, device); Vector3 backPosition2 = new Vector3(position.X + 2 * scale, position.Y, position.Z + scale); surfaces[7] = new Plane(backPosition2, backRotation, scale, device); Vector3 frontPosition = new Vector3(position.X, position.Y, position.Z - scale); Vector3 frontRotation = new Vector3(rotation.X - 0.5f * (float)Math.PI, rotation.Y, rotation.Z); surfaces[8] = new Plane(frontPosition, frontRotation, scale, device); Vector3 front2Position = new Vector3(position.X + 2 * scale, position.Y, position.Z - scale); ; surfaces[9] = new Plane(front2Position, frontRotation, scale, device); }
//Check for collision with a plane private CollisionInfo applyCollisionPhysics(Plane plane, Vector3 speed, Vector3 ballCollisionPoint, Vector3 speedInCollisionDirection, bool ignoreLength = false) { CollisionInfo collisionInfo = null; Vector3 newBallCollisionPoint = ballCollisionPoint + speed; //The new position, ignoring collisions Vector3 distanceVector = plane.getDistanceTillPoint(ballCollisionPoint); //The distance from bal to plane in the next frame Vector3 newDistanceVector = plane.getDistanceTillPoint(newBallCollisionPoint); //The distance from bal to plane in the previous frame if (!distanceVector.X.Equals(float.NaN) && !newDistanceVector.X.Equals(float.NaN)) { float distance = distanceVector.X + distanceVector.Y + distanceVector.Z; float newDistance = newDistanceVector.X + newDistanceVector.Y + newDistanceVector.Z; bool passesPlane = Math.Sign(distance) != Math.Sign(newDistance); if (ignoreLength || passesPlane) { Vector3 distanceTowardPlane = Physics.dotProductCalculation(distanceVector, plane.normal); if (ignoreLength || (Math.Sign(distanceTowardPlane.X) == Math.Sign(-plane.normal.X) || Math.Sign(distanceTowardPlane.Y) == Math.Sign(-plane.normal.Y) || Math.Sign(distanceTowardPlane.Z) == Math.Sign(-plane.normal.Z))) { collisionInfo = plane.getPivotWithLineAndDistanceTillBoundries(ballCollisionPoint, speed, radius); } } } return collisionInfo; }
//Check for collision with a plane private SpeedInfo applyCollisionPhysics(Plane plane, Vector3 speed) { SpeedInfo speedInfo; speedInfo.speed = speed; speedInfo.speedThisFrame = speed; Vector3 speedInNormalDirection = Physics.dotProductCalculation(speed, plane.normal); //Calculate the position of the end of the ball that is pointing toward the plane Vector3 ballCollisionPoint = getPivotWithPlane(plane.normal); CollisionInfo collisionInfo = applyCollisionPhysics(plane, speed, ballCollisionPoint, speedInNormalDirection); if (collisionInfo != null) { float maxDistance = Math.Max(Math.Abs(collisionInfo.distanceTillCollision.X), Math.Abs(collisionInfo.distanceTillCollision.Y)); if (collisionInfo.distanceTillCollision.Length() == 0) { speedInfo = bounce(speed, speedInNormalDirection, plane.normal); } else if (maxDistance <= radius) { //Calculate the position of the end of the ball that is pointing toward the plane Vector3 newPosition = ballCollisionPoint + speed; //The new position, ignoring collisions CollisionInfo centerCollisionInfo = applyCollisionPhysics(plane, speed, position, speedInNormalDirection, true); if (centerCollisionInfo != null) { Vector3 startingNormal = new Vector3(0, 1, 0); Vector3 planeNormal = plane.normal; planeNormal.Normalize(); Vector3 crossProduct = Vector3.Cross(startingNormal, planeNormal); crossProduct.Normalize(); Vector3 distanceTillCollision = new Vector3(collisionInfo.distanceTillCollision.X, -1+(float) Math.Sqrt(collisionInfo.distanceTillCollision.X * collisionInfo.distanceTillCollision.X + collisionInfo.distanceTillCollision.Y * collisionInfo.distanceTillCollision.Y), collisionInfo.distanceTillCollision.Y); if (!crossProduct.X.Equals(float.NaN) && !crossProduct.Y.Equals(float.NaN) && !crossProduct.Z.Equals(float.NaN)) { Quaternion q = new Quaternion(crossProduct.X, crossProduct.Y, crossProduct.Z, 1 + Vector3.Dot(startingNormal, planeNormal)); q.Normalize(); distanceTillCollision = Vector3.Transform(distanceTillCollision, q); } Vector3 offSet = distanceTillCollision; offSet = offSet * scale; Vector3 recalculatedBallCollisionPoint = position + offSet; Vector3 speedInCollisionDirection = Physics.dotProductCalculation(speed, offSet / scale); if (Math.Sign(speedInCollisionDirection.X) != Math.Sign(offSet.X) || Math.Sign(speedInCollisionDirection.Y) != Math.Sign(offSet.Y) || Math.Sign(speedInCollisionDirection.Y) != Math.Sign(offSet.Y)) { speedInCollisionDirection *= -1; } speedInfo = bounce(speed, speedInCollisionDirection, plane.normal); } } } return speedInfo; }