Example #1
0
        /// <summary>
        /// This is the overload you use when you call the constructor with the physics body
        /// </summary>
        public void Update()
        {
            if (_physicsBody == null)
            {
                throw new InvalidOperationException("This overload of update (no params) can't be called when there is no physics body");
            }

            Update(_physicsBody.PositionToWorld(_physicsBody.CenterOfMass), _physicsBody.VelocityCached, _showAcceleration ? _physicsBody.AccelerationCached : new Vector3D(0, 0, 0));          // only request acceleration if needed (the body has to do math if it's requested)
        }
Example #2
0
        private void Body_ApplyForce(Body sender, BodyForceEventArgs e)
        {
            ConvexBody3D senderCast = sender as ConvexBody3D;

            if (senderCast == null)
            {
                return;
            }

            #region Boundry Force

            Vector3D positionWorld = senderCast.PositionToWorld(senderCast.CenterOfMass).ToVector();

            // Just using one property from boundry assumes the boundry is square, and max is positive
            double boundryMax  = _boundryMax.X;
            double maxDistance = _boundryMax.X * .85d;
            if (positionWorld.LengthSquared > maxDistance * maxDistance)
            {
                // Get the distance from the max distance
                double distFromMax = positionWorld.Length - maxDistance;     // wait till now to do the expensive operation.

                // I want an acceleration of zero when distFromMax is 1, but an accel of 10 when it's boundryMax
                //NOTE: _boundryMax.X is to the edge of the box.  If they are in the corner the distance will be greater, so the accel will be greater
                double accel = UtilityCore.GetScaledValue(0, 30, 0, boundryMax - maxDistance, distFromMax);

                // Apply a force
                Vector3D force = positionWorld;
                force.Normalize();
                force *= accel * senderCast.Mass * -1d;
                e.AddForce(force);
            }

            #endregion

            #region Gravity

            if (_hasGravity)
            {
                //TODO:  Attract all other objects to the asteroids
                if (senderCast.MaterialGroupID == _materialManager.AsteroidMaterialID && _asteroidGravityForces.ContainsKey(senderCast))
                {
                    e.AddForce(_asteroidGravityForces[senderCast]);
                }
                else if (senderCast.MaterialGroupID == _materialManager.ShipMaterialID && _asteroidGravityForces.Keys.Count > 0)                // the asteroids only attract every few frames.  If I attract every frame, the forces are unbalanced, and the ship ends up propelling the asteroid around
                {
                    #region Ship to asteroids

                    Point3D shipPos  = senderCast.PositionToWorld(senderCast.CenterOfMass);
                    double  shipMass = senderCast.Mass;

                    Vector3D gravityForce = new Vector3D(0, 0, 0);

                    foreach (Asteroid asteroid in _asteroids)
                    {
                        #region Apply Gravity

                        Vector3D gravityLink = shipPos - asteroid.PositionWorld;

                        double force = GRAVITATIONALCONSTANT * (asteroid.Mass * shipMass) / gravityLink.LengthSquared;

                        gravityLink.Normalize();
                        gravityLink *= force;

                        //_asteroidGravityForces[_asteroids[innerCntr].PhysicsBody] += gravityLink;
                        gravityForce -= gravityLink;

                        #endregion
                    }

                    e.AddForce(gravityForce);

                    #endregion
                }
            }

            #endregion

            #region Set Velocities

            if (_setVelocityArgs != null)
            {
                _hasSetVelocities = true;

                // See if the velocity should be set for this type of object
                bool shouldSetVelocity = false;
                if (_setVelocityArgs.Asteroids && senderCast.MaterialGroupID == _materialManager.AsteroidMaterialID)
                {
                    shouldSetVelocity = true;
                }
                else if (_setVelocityArgs.Minerals && senderCast.MaterialGroupID == _materialManager.MineralMaterialID)
                {
                    shouldSetVelocity = true;
                }

                if (shouldSetVelocity)
                {
                    // Figure out the velocity
                    Vector3D velocity        = new Vector3D(0, 0, 0);
                    Vector3D angularVelocity = new Vector3D(0, 0, 0);
                    if (_setVelocityArgs.Speed > 0d)
                    {
                        velocity        = Math3D.GetRandomVector_Spherical(_setVelocityArgs.Speed);
                        angularVelocity = Math3D.GetRandomVector_Spherical(_setVelocityArgs.Speed / 10d);

                        if (_setVelocityArgs.IsRandom)
                        {
                            double halfSpeed = _setVelocityArgs.Speed / 2d;
                            if (velocity.Length < halfSpeed)
                            {
                                // It's going too slow, choose a new speed between half and full
                                velocity.Normalize();
                                double newSpeed = halfSpeed + (StaticRandom.NextDouble() * halfSpeed);
                                velocity *= newSpeed;
                            }
                        }
                        else
                        {
                            // GetRandomVectorSpherical returns random, but this should be fixed
                            velocity.Normalize();
                            velocity *= _setVelocityArgs.Speed;
                        }
                    }

                    // Set it (and clear rotation)
                    senderCast.Omega    = angularVelocity;
                    senderCast.Velocity = velocity;
                }
            }

            #endregion
        }
Example #3
0
        public void WorldUpdating(double elapsedTime)
        {
            #region Visuals

            foreach (ModelVisual3D model in _visuals)
            {
                if (model == _physicsModel)
                {
                    // The physics engine already transformed this one to world
                    continue;
                }

                // By setting this transform, is will render wherever the physics body is
                model.Transform = _physicsBody.Transform;
            }

            #endregion

            #region Thrust Lines

            Transform3D transform = _physicsBody.Transform;        // I just don't want to keep hitting the property
            foreach (List <ThrustLine> thrusts in _thrustLines.Values)
            {
                foreach (ThrustLine thrust in thrusts)
                {
                    thrust.DrawVisual(1d, transform);
                }
            }

            #endregion

            #region Swarmbots

            for (int cntr = 0; cntr < _swarmBots.Count; cntr++)
            {
                #region Swarm Bot Set

                //TODO:  Let the chase points rotate more loosely than the ship

                // Figure out the chase point
                Point3D  chasePoint             = _physicsBody.PositionToWorld(_swarmbotChasePoints[cntr]);
                Vector3D chasePointVelocity     = this.VelocityWorld;
                Vector3D chasePointAcceleration = _physicsBody.AccelerationCached;

                _swarmbotChasePointSprites[cntr].Update(chasePoint, chasePointVelocity, chasePointAcceleration);

                foreach (SwarmBot2 bot in _swarmBots[cntr])
                {
                    bot.ChasePoint         = chasePoint;
                    bot.ChasePointVelocity = chasePointVelocity;
                    bot.WorldUpdating();
                }

                #endregion
            }

            #endregion

            // Progress bars
            _progressBarFuel.Value = _fuelTank.QuantityCurrent;

            // I don't want to change the mass every frame (lots of calculations need to be made), so only do it if there is a
            // greater than 3% difference in mass
            //NOTE:  Currently only fuel is the variable mass, but there could be others in the future
            double totalMass = this.TotalMass;
            if (_lastSetMass == null || Math.Abs(totalMass - _lastSetMass.Value) > totalMass * .03d)
            {
                _physicsBody.Mass = Convert.ToSingle(totalMass);
                _lastSetMass      = totalMass;
            }
        }