예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
 /// <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);
     }
 }
예제 #5
0
        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());
        }
예제 #6
0
 public Collision(RadarBlip blip1, RadarBlip blip2)
 {
     this.Blip1 = blip1;
     this.Blip2 = blip2;
 }
예제 #7
0
 protected void PullItemsApartSpring_BallSphere(BallBlip ball, RadarBlip blip)
 {
 }
예제 #8
0
        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;
        }
예제 #9
0
        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;
            }
        }
예제 #10
0
        /// <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));
            }
        }
예제 #11
0
        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;

        }
예제 #12
0
        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;
        }
예제 #13
0
 /// <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);
 }
예제 #14
0
 public Collision(RadarBlip blip1, RadarBlip blip2)
 {
     this.Blip1 = blip1;
     this.Blip2 = 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
        }
예제 #16
0
        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();
        }
예제 #17
0
        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;
        }
예제 #18
0
        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;
        }
예제 #19
0
        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);
            }
        }
예제 #20
0
 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");
     }
 }
예제 #21
0
        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);
        }