示例#1
0
        public bool CollideAgainst(AxisAlignedCube axisAlignedCube)
        {
            BoundingBox boundingBox = axisAlignedCube.AsBoundingBox();


            float?result = this.AsRay().Intersects(boundingBox);

            return(result.HasValue && result.Value < this.GetLength());
        }
示例#2
0
        public PositionedObjectList <FlatRedBall.Math.Geometry.AxisAlignedCube> ToAxisAlignedCubeList()
        {
            PositionedObjectList <FlatRedBall.Math.Geometry.AxisAlignedCube> listToReturn = new PositionedObjectList <FlatRedBall.Math.Geometry.AxisAlignedCube>();

            foreach (AxisAlignedCubeSave cubeSave in AxisAlignedCubeSaves)
            {
                FlatRedBall.Math.Geometry.AxisAlignedCube cube = cubeSave.ToAxisAlignedCube();
                listToReturn.Add(cube);
            }

            return(listToReturn);
        }
示例#3
0
        /// <summary>
        /// Returns whether this instance overlaps the argument AxisAlignedCube
        /// </summary>
        /// <param name="cube">The instance AxisAlignedCube to test against.</param>
        /// <returns>Whether collision has occurred</returns>
        public bool CollideAgainst(AxisAlignedCube cube)
        {
            UpdateDependencies(TimeManager.CurrentTime);
            cube.UpdateDependencies(TimeManager.CurrentTime);

            Vector3 relativeCenter = Position - cube.Position;

            if (System.Math.Abs(relativeCenter.X) - Radius > cube.ScaleX ||
                System.Math.Abs(relativeCenter.Y) - Radius > cube.ScaleY ||
                System.Math.Abs(relativeCenter.Z) - Radius > cube.ScaleZ)
            {
                return(false);
            }

            Vector3 nearest = GetNearestPoint(cube, relativeCenter);

            float distance = (nearest - relativeCenter).LengthSquared();

            return(distance <= Radius * Radius);
        }
示例#4
0
        private Vector3 GetNearestPoint(AxisAlignedCube cube, Vector3 relativeCenter)
        {
            float   distance;
            Vector3 nearest = new Vector3();

            distance = relativeCenter.X;
            if (distance > cube.ScaleX)
            {
                distance = cube.ScaleX;
            }
            if (distance < -cube.ScaleX)
            {
                distance = -cube.ScaleX;
            }
            nearest.X = distance;

            distance = relativeCenter.Y;
            if (distance > cube.ScaleY)
            {
                distance = cube.ScaleY;
            }
            if (distance < -cube.ScaleY)
            {
                distance = -cube.ScaleY;
            }
            nearest.Y = distance;

            distance = relativeCenter.Z;
            if (distance > cube.ScaleZ)
            {
                distance = cube.ScaleZ;
            }
            if (distance < -cube.ScaleZ)
            {
                distance = -cube.ScaleZ;
            }
            nearest.Z = distance;

            return(nearest);
        }
示例#5
0
        /// <summary>
        /// Performs a bounce collision (a collision which modifies velocity and acceleration), and separates the objects if so.
        /// </summary>
        /// <param name="cube">The cube to perform collision against.</param>
        /// <param name="thisMass">The mass of this instance.</param>
        /// <param name="otherMass">Th e mass of the argument cube.</param>
        /// <param name="elasticity">The ratio of velocity to preserve.</param>
        /// <returns>Whether a collision occurred.</returns>
        public bool CollideAgainstBounce(AxisAlignedCube cube, float thisMass, float otherMass, float elasticity)
        {
#if DEBUG
            if (thisMass == 0 && otherMass == 0)
            {
                throw new ArgumentException("Both masses cannot be 0.  For equal masses pick a non-zero value");
            }
#endif
            if (CollideAgainstMove(cube, thisMass, otherMass))
            {
                // Get the relative velocity of this circle to the argument circle:
                Vector3 relativeVelocity = new Vector3(
                    this.TopParent.XVelocity - cube.TopParent.XVelocity,
                    this.TopParent.YVelocity - cube.TopParent.YVelocity,
                    this.TopParent.ZVelocity - cube.TopParent.ZVelocity);

                Vector3 reposition = LastMoveCollisionReposition;

                if (otherMass == 0)
                {
                    reposition = -cube.mLastMoveCollisionReposition;
                }
#if FRB_MDX
                float velocityNormalDotResult = Vector3.Dot(relativeVelocity, reposition);
#else
                float velocityNormalDotResult;
                Vector3.Dot(ref relativeVelocity, ref reposition, out velocityNormalDotResult);
#endif

                if (velocityNormalDotResult >= 0)
                {
                    return(true);
                }

#if FRB_MDX
                throw new NotImplementedException();

                //Vector2 tangentVector = new Vector2((float)mLastCollisionTangent.X, (float)mLastCollisionTangent.Y);
                //// Perform the bounce if the relative velocity and the tangent are the opposite direction.

                Vector3 reverseNormal = -Vector3.Normalize(LastMoveCollisionReposition);

                float   length           = Vector3.Dot(relativeVelocity, reverseNormal);
                Vector3 velocityOnNormal = Vector3.Multiply(reverseNormal, length);
#else
                Vector3 reverseNormal = -reposition;
                reverseNormal.Normalize();

                float   length = Vector3.Dot(relativeVelocity, reverseNormal);
                Vector3 velocityOnNormal;
                Vector3.Multiply(ref reverseNormal, length, out velocityOnNormal);
#endif


                cube.TopParent.Velocity.X += (1 + elasticity) * thisMass / (thisMass + otherMass) * velocityOnNormal.X;
                cube.TopParent.Velocity.Y += (1 + elasticity) * thisMass / (thisMass + otherMass) * velocityOnNormal.Y;
                cube.TopParent.Velocity.Z += (1 + elasticity) * thisMass / (thisMass + otherMass) * velocityOnNormal.Z;

                this.TopParent.Velocity.X -= (1 + elasticity) * otherMass / (thisMass + otherMass) * velocityOnNormal.X;
                this.TopParent.Velocity.Y -= (1 + elasticity) * otherMass / (thisMass + otherMass) * velocityOnNormal.Y;
                this.TopParent.Velocity.Z -= (1 + elasticity) * otherMass / (thisMass + otherMass) * velocityOnNormal.Z;

                return(true);
            }
            return(false);
        }
示例#6
0
        /// <summary>
        /// Returns whether this instance overlaps the argument cube, and separates the two instances according to their relative masses.
        /// </summary>
        /// <param name="cube">The cube to perform collision against.</param>
        /// <param name="thisMass">The mass of this instance.</param>
        /// <param name="otherMass">The mass of the cube.</param>
        /// <returns>Whether the objects were overlapping before the reposition.</returns>
        public bool CollideAgainstMove(AxisAlignedCube cube, float thisMass, float otherMass)
        {
#if DEBUG
            if (thisMass == 0 && otherMass == 0)
            {
                throw new ArgumentException("Both masses cannot be 0.  For equal masses pick a non-zero value");
            }
#endif
            if (LastDependencyUpdate != TimeManager.CurrentTime)
            {
                UpdateDependencies(TimeManager.CurrentTime);
            }
            if (cube.LastDependencyUpdate != TimeManager.CurrentTime)
            {
                cube.UpdateDependencies(TimeManager.CurrentTime);
            }


            Vector3 relativeCenter = Position - cube.Position;

            if (System.Math.Abs(relativeCenter.X) - Radius > cube.ScaleX ||
                System.Math.Abs(relativeCenter.Y) - Radius > cube.ScaleY ||
                System.Math.Abs(relativeCenter.Z) - Radius > cube.ScaleZ)
            {
                return(false);
            }

            Vector3 nearest = GetNearestPoint(cube, relativeCenter);

            float distance = (nearest - relativeCenter).LengthSquared();

            if (distance > Radius * Radius)
            {
                return(false);
            }

            double  distanceToMove = Radius - System.Math.Sqrt((double)distance);
            Vector3 moveVector     = relativeCenter - nearest;
            moveVector.Normalize();

            float amountToMoveThis = otherMass / (thisMass + otherMass);

            LastMoveCollisionReposition = moveVector * (float)(distanceToMove * amountToMoveThis);

            Vector3 cubeReposition = moveVector * (float)(-distanceToMove * (1 - amountToMoveThis));
            cube.mLastMoveCollisionReposition = cubeReposition;

            if (mParent != null)
            {
                TopParent.Position += LastMoveCollisionReposition;
                ForceUpdateDependencies();
            }
            else
            {
                Position += LastMoveCollisionReposition;
            }

            if (cube.mParent != null)
            {
                cube.TopParent.Position += cube.LastMoveCollisionReposition;
                ForceUpdateDependencies();
            }
            else
            {
                cube.Position += cube.LastMoveCollisionReposition;
            }

            return(true);
        }