예제 #1
0
        private void Body_ApplyForce(Body sender, BodyForceEventArgs e)
        {
            if (sender != _physicsBody)
            {
                return;
            }

            if (!_hasSetInitialVelocity)
            {
                e.AddImpulse(_initialVelocity, Math3D.GetRandomVector_Spherical(this.Radius * .5d));     // whacking it at an offset, so it has some rotation as well
                _hasSetInitialVelocity = true;

                // No need to listen to this even anymore
                _physicsBody.ApplyForce -= new BodyForceEventHandler(Body_ApplyForce);
            }
        }
예제 #2
0
        private void Body_ApplyForce(Body sender, BodyForceEventArgs e)
        {
            if (sender != _physicsBody)
            {
                return;
            }

            #region Thrusters

            if (_thrustTransform != null && _thrustPercent > 0d)
            {
                _thruster.ApplyForce(_thrustPercent, _physicsBody.Transform, _thrustTransform, e);
            }

            #endregion
        }
예제 #3
0
        /// <summary>
        /// Call this to apply the thruster force to the physics body
        /// </summary>
        public void ApplyForce(double percentMax, Transform3D worldTransform, BodyForceEventArgs e)
        {
            if (!_isFiring)        // the property set will make sure the visual is no longer known to the viewport
            {
                return;
            }

            double actualForce = _forceStrength * percentMax;
            if (_fuelTank != null)
            {
                #region Use Fuel

                if (_fuelTank.QuantityCurrent > 0d)
                {
                    double fuelToUse = actualForce * e.ElapsedTime * _fuelToThrustRatio;

                    double fuelUnused = _fuelTank.RemoveQuantity(fuelToUse, false);
                    if (fuelUnused > 0d)
                    {
                        // Not enough fuel, reduce the amount of force
                        actualForce -= fuelUnused / (e.ElapsedTime * _fuelToThrustRatio);
                    }
                }
                else
                {
                    actualForce = 0d;
                }

                #endregion
            }

            if (actualForce == 0d)
            {
                // No force to apply
                //TODO:  Play a clicking sound, or some kind of error tone
                //TODO:  Don't show the flames
                return;
            }

            // Figure out how to place it in world coords
            Transform3DGroup transform = new Transform3DGroup();       // I don't use _initialRotate, because that's for the visual (it's always created along the X axis, but _force is already stored correctly)
            transform.Children.Add(this.BodyOffset);
            transform.Children.Add(worldTransform);

            Vector3D positionOnBodyWorld = transform.Transform(new Point3D(0, 0, 0)).ToVector();    // note that I have to use a point (transform acts different on points than vectors)
            Vector3D deltaForceWorld = transform.Transform(_forceDirection);
            deltaForceWorld.Normalize();
            deltaForceWorld *= actualForce;

            // Apply the force
            e.AddForceAtPoint(deltaForceWorld, positionOnBodyWorld);
        }
예제 #4
0
        public void ApplyForce(double percentMax, Transform3D worldTransform, Transform3D localSteeringTransform, BodyForceEventArgs e)
        {
            if (!_isFiring)        // the property set will make sure the visual is no longer known to the viewport
            {
                return;
            }

            // Combine the two, and call my other overload
            Transform3DGroup transformGroup = new Transform3DGroup();
            transformGroup.Children.Add(localSteeringTransform);
            transformGroup.Children.Add(worldTransform);

            ApplyForce(percentMax, transformGroup, e);
        }
예제 #5
0
        private void Body_ApplyForce(Body sender, BodyForceEventArgs e)
        {
            if (sender != _physicsBody)
            {
                return;
            }
            //e.ElapsedTime
            #region Thrusters

            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.ApplyForce(1d, transform, e);
                }
            }

            #endregion
        }
 private void Body_ApplyForce(Body sender, BodyForceEventArgs e)
 {
 }
        private void Body_ApplyForce(Body sender, BodyForceEventArgs e)
        {
            // Apply Gravity
            if (!_bodyForces.ContainsKey(sender))
            {
                return;
            }

            e.AddForce(_bodyForces[sender]);
        }
        private void Cube_ApplyForce(Body sender, BodyForceEventArgs e)
        {
            if (_shouldRandomizeVelocities)
            {
                #region Set Velocities

                _didRandomizeVelocities = true;

                Vector3D newVelocity = Math3D.GetRandomVector_Spherical(MAXRANDVELOCITY * _randVelMultiplier);

                //sender.Velocity.X = newVelocity.X;
                //sender.Velocity.Y = newVelocity.Y;
                //sender.Velocity.Z = newVelocity.Z;

                e.AddImpulse(newVelocity, sender.CenterOfMass.ToVector());

                #endregion
            }

            #region Do Gravity

            // Calculate force between the two
            //TODO:  Calculate these forces in one place and remember the results


            Point3D blueCenterWorld = GetWorldCenterMass(_blueCube);
            Point3D redCenterWorld = GetWorldCenterMass(_redCube);

            Vector3D gravityLink = blueCenterWorld - redCenterWorld;

            double force = GRAVITATIONALCONSTANT * (_blueCube.Mass * _redCube.Mass) / gravityLink.LengthSquared;

            gravityLink.Normalize();
            gravityLink = Vector3D.Multiply(force, gravityLink);

            // Apply the force
            if (sender == _blueCube)
            {
                e.AddForce(Vector3D.Multiply(-1d, gravityLink));
            }
            else if (sender == _redCube)
            {
                e.AddForce(gravityLink);
            }
            else
            {
                MessageBox.Show("Unknown Sender: " + sender.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            #endregion
        }
        private void Body_ApplyForce(Body sender, BodyForceEventArgs e)
        {
            if (_shouldRandomizeVelocities)
            {
                #region Set Velocities

                _didRandomizeVelocities = true;

                Vector3D newVelocity = Math3D.GetRandomVector_Spherical(MAXRANDVELOCITY * _randVelMultiplier);

                e.AddImpulse(newVelocity, sender.CenterOfMass.ToVector());

                #endregion
            }

            // Apply Gravity
            if (!_cubeForces.ContainsKey(sender))
            {
                return;
            }

            e.AddForce(_cubeForces[sender]);
        }
예제 #10
0
        private void Body_ApplyForce(Body sender, BodyForceEventArgs e)
        {
            if (sender != _physicsBody)
            {
                return;
            }

            if (!_hasSetInitialVelocity)
            {
                e.AddImpulse(_initialVelocity, new Vector3D(0, 0, 0));
                _hasSetInitialVelocity = true;

                // No need to listen to this even anymore
                _physicsBody.ApplyForce -= new BodyForceEventHandler(Body_ApplyForce);
            }
        }
예제 #11
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
        }