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) { // Apply Gravity if (!_bodyForces.ContainsKey(sender)) { return; } e.AddForce(_bodyForces[sender]); }
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]); }
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 }