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); } }
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 }
/// <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); }
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); }
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]); }
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); } }
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 }