public RadarBlip[] GetAllBlips() { RadarBlip[] retVal = new RadarBlip[_blips.Values.Count]; for (int blipCntr = 0; blipCntr < retVal.Length; blipCntr++) { retVal[blipCntr] = _blips.Values[blipCntr]; } return(retVal); }
/// <summary> /// This function will remove the blip from my knowledge. I give you the pointer to it in case you want to keep it. /// </summary> /// <remarks> /// For example, if you pick up a rock, call this function, and you will be the parent of that rock. But, if you throw the /// rock, you will need to give the rock back to me. The reason I went with that approach, is because I don't want to be /// in charge of all the items that you are carrying. It gets more complex if you put an item in your pocket. Now that /// item is concealed. /// /// There are two modes of an item being hidden. There is completely hidden, which means the Audio/Visual class will /// be turned off, and there is hidden from my collision detection. For my collision detection to work, whenever you /// pick up an item that needs to be included in collision checks, you will need to modify your radius so that the radius /// encompasses all objects that you are holding. /// </remarks> public RadarBlip Remove(long token) { RadarBlip retVal = _blips[token]; // See if I should wait if (_isTimerRunning) { _removeRequests.Add(token); return(retVal); } // Remove it _blips.Remove(token); _nonCollidableBlips.Remove(retVal); // it is only in one of the lists, but the style may change in the middle of a tick _collidableBlips.Remove(retVal); // Exit Function return(retVal); }
public void Add(RadarBlip blip) { // See if I should wait if (_isTimerRunning) { _addRequests.Add(blip); return; } // Add it _blips.Add(blip.Token, blip); if (blip.CollisionStyle == CollisionStyle.Ghost) { _nonCollidableBlips.Add(blip); } else { _collidableBlips.Add(blip); } }
/// <summary> /// This function pulls the two blips straight apart from each other (no physics involved, just displacement) /// </summary> public virtual void PullItemsApartInstant(RadarBlip blip1, RadarBlip blip2) { if (blip1 is BallBlip && blip2 is BallBlip) { // They're both at least balls, use mass and radius in the calculation PullItemsApartInstant_BallBall((BallBlip)blip1, (BallBlip)blip2); } else { // At least one is a sphere. Use radius in the calculation PullItemsApartInstant_SphereSphere(blip1, blip2); } }
private bool SelectionTest(RadarBlip blip, MyVector rectCorner1, MyVector rectCorner2) { // Just worry about spheres for now // I'll just cheat and let the rectangle do the work for me. There are several flaws with this, but it // works for now MyVector topLeft, bottomRight; GetProperCorners(out topLeft, out bottomRight, rectCorner1, rectCorner2); RectangleF rect = new RectangleF(topLeft.ToPointF(), new SizeF(Convert.ToSingle(bottomRight.X - topLeft.X), Convert.ToSingle(bottomRight.Y - topLeft.Y))); return rect.Contains(blip.Sphere.Position.ToPointF()); }
public Collision(RadarBlip blip1, RadarBlip blip2) { this.Blip1 = blip1; this.Blip2 = blip2; }
protected void PullItemsApartSpring_BallSphere(BallBlip ball, RadarBlip blip) { }
private bool SelectionTest(RadarBlip blip, MyVector point) { // Just worry about spheres for now MyVector line = point - blip.Sphere.Position; return line.GetMagnitude() <= blip.Sphere.Radius; }
protected CollisionDepth IsColliding_SphereSphere(RadarBlip sphere1, RadarBlip sphere2) { MyVector lineBetween = sphere2.Sphere.Position - sphere1.Sphere.Position; double distanceSquared = lineBetween.GetMagnitudeSquared(); double sumRadii = sphere1.Sphere.Radius + sphere2.Sphere.Radius; // See if they missed each other if (distanceSquared > sumRadii * sumRadii) { return CollisionDepth.NotColliding; } double distance = Math.Sqrt(distanceSquared); double percentPenetrating = (sumRadii - distance) / sumRadii; if (percentPenetrating <= _penetrationThresholdPercent) { return CollisionDepth.Touching; } else { return CollisionDepth.Penetrating; } }
/// <summary> /// This function pulls the items directly apart based on the ratio of their radii /// </summary> protected void PullItemsApartInstant_SphereSphere(RadarBlip sphere1, RadarBlip sphere2) { // Get the vector from 2 to 1 MyVector move1From2 = sphere1.Sphere.Position - sphere2.Sphere.Position; double totalDistance = move1From2.GetMagnitude() * _pullApartInstantPercent; // distance from centers (exagerated by the percent passed in) double actualDistance = (sphere1.Sphere.Radius + sphere2.Sphere.Radius) - totalDistance; // distance from edges // Make this a unit vector move1From2.Divide(totalDistance); double ratio1 = sphere1.Sphere.Radius / (sphere1.Sphere.Radius + sphere2.Sphere.Radius); // Set their positions if (sphere1.CollisionStyle == CollisionStyle.Standard) { sphere1.Sphere.Position.Add(move1From2 * (actualDistance * ratio1)); } if (sphere2.CollisionStyle == CollisionStyle.Standard) { sphere2.Sphere.Position.Add(move1From2 * (actualDistance * (1d - ratio1) * -1d)); } }
private bool WillCollide(Ball ball) { // Make a temp blip to be a wrapper for this RadarBlip blip = new RadarBlip(ball, CollisionStyle.Standard, RadarBlipQual.BallUserDefined10, TokenGenerator.NextToken()); foreach (RadarBlip existingBlip in _map.GetAllBlips()) { if (_map.CollisionHandler.IsColliding(blip, existingBlip) != CollisionDepth.NotColliding) { // It's colliding return true; } } return false; }
public virtual bool Collide(RadarBlip blip1, RadarBlip blip2) { if (blip1.CollisionStyle == CollisionStyle.Ghost || blip2.CollisionStyle == CollisionStyle.Ghost) { // I won't even bother trying to collide ghosts return false; } if (!(blip1 is BallBlip)) { return false; } if (!(blip2 is BallBlip)) { return false; } // If I am here, they are both balls. BallBlip ballBlip1 = blip1 as BallBlip; BallBlip ballBlip2 = blip2 as BallBlip; if (ballBlip1.TorqueBall != null && ballBlip2.TorqueBall != null) { #region Treat them like solid balls if (ballBlip1.CollisionStyle == CollisionStyle.Standard) { if (ballBlip2.CollisionStyle == CollisionStyle.Standard) { // Two standard balls Collide_TorqueBallTorqueBall(ballBlip1, ballBlip2); } else { // One is standard, two is stationary Collide_TorqueBallTorqueBall_2IsStationary(ballBlip1, ballBlip2); } } else if (ballBlip2.CollisionStyle == CollisionStyle.Standard) { // One is stationary, two is standard Collide_TorqueBallTorqueBall_2IsStationary(ballBlip2, ballBlip1); } // No need for an else. There is nothing to do (both are stationary) #endregion } else if (ballBlip1.TorqueBall == null && ballBlip2.TorqueBall == null) { #region Treat them like regular balls //TODO: Handle a ball colliding with a torqueball if (ballBlip1.CollisionStyle == CollisionStyle.Standard) { if (ballBlip2.CollisionStyle == CollisionStyle.Standard) { // Two standard balls Collide_BallBall(ballBlip1, ballBlip2); } else { // One is standard, two is stationary Collide_BallBall_2IsStationary(ballBlip1, ballBlip2); } } else if (ballBlip2.CollisionStyle == CollisionStyle.Standard) { // One is stationary, two is standard Collide_BallBall_2IsStationary(ballBlip2, ballBlip1); } // No need for an else. There is nothing to do (both are stationary) #endregion } else if (ballBlip1.TorqueBall != null) { // 1 is torqueball, 2 is regular ball CollideSprtBallTorqueBall(ballBlip2, ballBlip1); } else //if (ballBlip2.TorqueBall != null) { // 1 is regular ball, 2 is torqueball CollideSprtBallTorqueBall(ballBlip1, ballBlip2); } return true; }
/// <summary> /// This function will compare the two blips to see if they're touching or not /// NOTE: This function DOES NOT check CollisionStyles of the blips. So if you can't gracefully handle /// stationary penetrating blips, then don't call this function in that case. /// </summary> /// <remarks> /// I will examine the types of blips to see what type of check to do (sphere on sphere, sphere on poly, poly on poly) /// </remarks> public virtual CollisionDepth IsColliding(RadarBlip blip1, RadarBlip blip2) { // For now, I will just assume they are spheres return IsColliding_SphereSphere(blip1, blip2); }
private void HurtBlip(Projectile projectile, RadarBlip blip) { #region See if a split should occur if (blip.CollisionStyle != CollisionStyle.Standard) { return; } if (!(blip is BallBlip)) { return; } BallBlip castBlip = (BallBlip)blip; double ratio = projectile.Pain / castBlip.Ball.Mass; double rand = _rand.NextDouble(); if (ratio < rand) { return; } #endregion #region Calculate Split Percents int numParts = 2 + _rand.Next(3); // between 2 and 4 parts double[] splitPercents = new double[numParts]; double remainder = 1d; for (int cntr = 0; cntr < numParts - 1; cntr++) { splitPercents[cntr] = _rand.NextDouble() * remainder; remainder -= splitPercents[cntr]; } splitPercents[numParts - 1] = remainder; #endregion #region Build Objects _map.Remove(blip.Token); foreach (double percent in splitPercents) { double size = castBlip.Ball.Mass * percent; if (size < 20) { continue; } Ball ball; if (castBlip.Ball is SolidBall) { ball = new SolidBall(castBlip.Ball.Position.Clone(), castBlip.Ball.OriginalDirectionFacing.Clone(), size, size, castBlip.Ball.Elasticity, castBlip.Ball.KineticFriction, castBlip.Ball.StaticFriction, _boundryLower, _boundryUpper); } else { ball = new Ball(castBlip.Ball.Position.Clone(), castBlip.Ball.OriginalDirectionFacing.Clone(), size, size, castBlip.Ball.Elasticity, castBlip.Ball.KineticFriction, castBlip.Ball.StaticFriction, _boundryLower, _boundryUpper); } ball.Velocity.StoreNewValues(castBlip.Ball.Velocity); //TODO: Lay them out so they aren't touching each other. The smallest ones should be closest // to the point of impact (maybe give them slightly tweaked velocities as well so they explode // outward) _map.Add(new BallBlip(ball, blip.CollisionStyle, blip.Qual, TokenGenerator.NextToken())); } #endregion }
private void DrawScene(RadarBlip[] blips) { pictureBox1.ZoomFit(); pictureBox1.PrepareForNewDraw(); // _personalRenderer.Viewer is picturebox1 // Draw all the blips foreach (RadarBlip blip in blips) { // Draw the blip if (blip.Sphere is RigidBody) { _personalRenderer.DrawRigidBody((RigidBody)blip.Sphere, ObjectRenderer.DrawMode.Standard, blip.CollisionStyle, false); } else if (blip.Sphere is SolidBall) { _personalRenderer.DrawSolidBall((SolidBall)blip.Sphere, ObjectRenderer.DrawMode.Standard, blip.CollisionStyle, false); } else if (blip.Sphere is Ball) { _personalRenderer.DrawBall((Ball)blip.Sphere, ObjectRenderer.DrawMode.Standard, blip.CollisionStyle, false); } else { throw new ApplicationException("Unknown Blip"); } } pictureBox1.FinishedDrawing(); }
public static RadarBlip CloneBlip(RadarBlip blip, SimpleMap map) { BallBlip retVal = new BallBlip((Ball)blip.Sphere.Clone(), blip.CollisionStyle, blip.Qual, TokenGenerator.NextToken()); retVal.Ball.Velocity.StoreNewValues(((Ball)blip.Sphere).Velocity); if (blip.Sphere is TorqueBall) { ((TorqueBall)retVal.Sphere).AngularMomentum.StoreNewValues(((TorqueBall)blip.Sphere).AngularMomentum); } return retVal; }
public RadarBlip[] GetAllBlips() { RadarBlip[] retVal = new RadarBlip[_blips.Values.Count]; for (int blipCntr = 0; blipCntr < retVal.Length; blipCntr++) { retVal[blipCntr] = _blips.Values[blipCntr]; } return retVal; }
public virtual void PullItemsApartSpring(RadarBlip blip1, RadarBlip blip2) { if (blip1 is BallBlip && blip2 is BallBlip) { PullItemsApartSpring_BallBall((BallBlip)blip1, (BallBlip)blip2); } else if (blip1 is BallBlip) { PullItemsApartSpring_BallSphere((BallBlip)blip1, blip2); } else if (blip2 is BallBlip) { PullItemsApartSpring_BallSphere((BallBlip)blip2, blip1); } else { throw new ArgumentOutOfRangeException("Can't apply a spring force to non-balls"); } }
private void ApplyExplosionForce(RadarBlip blip) { if (!(blip is BallBlip)) { return; } BallBlip castBlip = (BallBlip)blip; MyVector force = castBlip.Ball.Position - this.Ball.Position; force.BecomeUnitVector(); force.Multiply(_explosion.Force); // Setting the force does no good, because PrepareForNewTick is called before it can take affect //castBlip.Ball.ExternalForce.Add(force); force.Divide(castBlip.Ball.Mass); // F=MA castBlip.Ball.Velocity.Add(force); }