private MyVector GetSpinVelocityAtPoint(ref AngularVelocityInfo angularInfo, out MyVector dirToCenterLine, MyVector dirFacingWorld, MyVector lineBetween, MyVector blipPosition) { // Get a line that's orthogonal to lineBetween, and always points toward the dirFacingWorld vector dirToCenterLine = MyVector.Cross(MyVector.Cross(lineBetween, dirFacingWorld), lineBetween); dirToCenterLine.BecomeUnitVector(); if (angularInfo == null) { #region Cache Angular Velocity angularInfo = new AngularVelocityInfo(); if (_ship.TorqueBall != null) { angularInfo.AngularVelocity = _ship.TorqueBall.AngularVelocity.GetMagnitude(); angularInfo.SpinDirection = MyVector.Cross(_ship.TorqueBall.AngularVelocity, _ship.TorqueBall.DirectionFacing.Standard); angularInfo.SpinDirection.BecomeUnitVector(); angularInfo.CenterMass = _ship.TorqueBall.Rotation.GetRotatedVector(_ship.TorqueBall.CenterOfMass, true); angularInfo.CenterMass.Add(_ship.TorqueBall.Position); } else { angularInfo.SpinDirection = dirToCenterLine.Clone(); angularInfo.AngularVelocity = 0d; angularInfo.CenterMass = _ship.Ball.Position.Clone(); } #endregion } // Get the line between the blip and the center of mass MyVector lineBetweenCM = blipPosition - angularInfo.CenterMass; // Figure out my velocity of spin where the blip is return(angularInfo.SpinDirection * (angularInfo.AngularVelocity * lineBetweenCM.GetMagnitude())); }
private List <Interaction> GetInteractions_Standard(out double totalForce, MyVector centerWorld, MyVector dirFacingWorld) { totalForce = 0d; List <Interaction> retVal = new List <Interaction>(); AngularVelocityInfo tractorAngularInfo = null; // Scan for objects in my path foreach (BallBlip blip in FindBlipsInCone(centerWorld, dirFacingWorld)) { // Get the distance MyVector lineBetween = blip.Sphere.Position - centerWorld; double distance = lineBetween.GetMagnitude(); // Figure out the force to apply double force = UtilityCore.GetScaledValue(_forceAtZero, _forceAtMax, 0d, _maxDistance, distance); force *= _percent; switch (_mode) { case BeamMode.PushPull: #region Push Pull if (!Utility3D.IsNearZero(distance)) { // Turn lineBetween into a unit vector (it will be multiplied by force later) lineBetween.BecomeUnitVector(); if (_isSoft) { force = GetForceForSoft(ref tractorAngularInfo, force, lineBetween, distance, blip.Ball, dirFacingWorld); } // Add this to the return list retVal.Add(new Interaction(blip, lineBetween, force)); totalForce += Math.Abs(force); // percent is negative when in repulse mode } #endregion break; case BeamMode.LeftRight: #region Left Right // Only do something if the lines aren't sitting directly on top of each other (even if they want to repel, // I'd be hesitant to just repel in any random direction) if (!Utility3D.IsNearValue(MyVector.Dot(lineBetween, dirFacingWorld, true), 1d)) { // Get a line that's orthogonal to lineBetween, and always points toward the dirFacingWorld vector MyVector dirToCenterLine = MyVector.Cross(lineBetween, MyVector.Cross(lineBetween, dirFacingWorld)); dirToCenterLine.BecomeUnitVector(); // Add to the return list retVal.Add(new Interaction(blip, dirToCenterLine, force)); totalForce += Math.Abs(force); // percent is negative when in repulse mode } #endregion break; default: throw new ApplicationException("Unknown BeamMode: " + _mode.ToString()); } } // Exit Function return(retVal); }