private Sphere CollisionCylinder(Cylinder c, Sphere s, Matrix4 Level) { Vector3 L1p = new Vector3(0, 1, 0); Vector3 L2p = new Vector3(0, -1, 0); L1p = Vector3.Transform(L1p, (c.TranslationMatrix * Level)); L2p = Vector3.Transform(L2p, (c.TranslationMatrix * Level)); Vector3 SquareSideDirection = ((L1p - L2p)); SquareSideDirection.Normalize(); Vector3 Cp = s.mPosition; //Parrell position on the square Vector3 A = (Vector3.Dot((Cp - L2p), SquareSideDirection) * SquareSideDirection); float AStrength = (Vector3.Dot((Cp - L2p), SquareSideDirection)); Vector3 VectorFromSquare = L2p + A - Cp; if (A.Length < (L1p - L2p).Length && AStrength > 0) //If A is within the square { if (VectorFromSquare.Length < s.mRadius + c.mRadius) { Vector3 normal; normal = (s.mPosition - (L2p + A)); normal.Normalize(); s.mPosition = s.mOldPosition; s.mVelocity = CalculateVelocity(normal, s.mVelocity); } } return(s); }
public bool CheckFor_SphereCylinder_Collision(Cylinder cylinder, Ball ball, ShaderUtility mShader) { Vector4 vPoint1, centre, vPoint2; float cylinderRadius, clen; //Radius and Length of the Cylinder. Matrix4 mObjRotation; //Cylinder Transformation data. cylinder.GetCollisionData(out centre, out clen, out mObjRotation, out cylinderRadius); vPoint1 = centre + new Vector4(0, ACWWindow.Centimetre * (clen / 2), 0, 0); vPoint2 = centre - new Vector4(0, ACWWindow.Centimetre * (clen / 2), 0, 0); float modifierPercentage = ball.radius + ball.radius / 2; //for extrapolating the previous position. vPoint1 = Vector4.Transform((vPoint1), mObjRotation); vPoint2 = Vector4.Transform((vPoint2), mObjRotation); #region horrible_horribe_hacky_thing_oh_please_fix_this if (Math.Abs(vPoint1.X) - Math.Abs(vPoint1.Z) > 1 || Math.Abs(vPoint1.Z) - Math.Abs(vPoint1.X) > 1) { if (Math.Abs(vPoint1.X) > Math.Abs(vPoint1.Z)) { vPoint1.Z = centre.Z; vPoint2.Z = centre.Z; } else { vPoint1.X = centre.X; vPoint2.X = centre.X; } } vPoint1.Y = centre.Y; vPoint2.Y = centre.Y; #endregion //Line Collision Algorith Vector4 vP2toCentre = ball.vPosition - vPoint2; Vector4 vP2P1_normal = (vPoint1 - vPoint2).Normalized(); Vector4 adjSide = Vector4.Dot(vP2toCentre, vP2P1_normal) * vP2P1_normal; float len = adjSide.Length; Vector4 vCentreToEdge = vPoint2 + (adjSide - ball.vPosition); Vector4 pointOfImpact = vPoint2 + adjSide; #region visualisation_stuff if (vCentreToEdge.Length < ball.DistanceToNearestObject) { ball.DistanceToNearestObject = vCentreToEdge.Length; ball.NearestContact = (pointOfImpact - ball.vPosition).Normalized() * ball.DistanceToNearestObject * 2;//Vector4.Transform(iPoint, mObjRotation.Inverted()); } #endregion if (vCentreToEdge.Length < ((ball.radius + cylinderRadius) * ACWWindow.Centimetre) || vCentreToEdge.Length < 0) //(vCentreToEdge.Length < mCircleRadius[circleID]) { //if (len > 0 && len < (vPoint1 - vPoint2).Length) //Check not really needed if we're not considering anything outside the box... { ball.vPosition = ball.vOldPosition; Vector4 normal = -vCentreToEdge; normal = normal.Normalized(); React_SphereImmovableObject(ball, normal); return(true); } } return(false); }