Esempio n. 1
0
 private void OnEnable()
 {
     if (_moverReference == null)
     {
         _moverReference = GetComponent <KeplerOrbitMover>();
     }
 }
        private List <Vector3d> CalculateVelocityDifference(KeplerOrbitMover a, KeplerOrbitMover b, KeplerOrbitData transitionOrbit, double departureTime, double duration, double eccAnomalyDeparture, double eccAnomalyArrival)
        {
            var aMeanAnomalyAtDeparture = a.OrbitData.MeanAnomaly + a.OrbitData.MeanMotion * departureTime;
            var aEccAnomAtDeparture     = KeplerOrbitUtils.ConvertMeanToEccentricAnomaly(aMeanAnomalyAtDeparture, a.OrbitData.Eccentricity);
            var aVelocityAtDeparture    = a.OrbitData.GetVelocityAtEccentricAnomaly(aEccAnomAtDeparture);

            var bMeanAnomalyAtArrival = b.OrbitData.MeanAnomaly + b.OrbitData.MeanMotion * (departureTime + duration);
            var bEccAnomAtArrival     = KeplerOrbitUtils.ConvertMeanToEccentricAnomaly(aMeanAnomalyAtDeparture, a.OrbitData.Eccentricity);
            var bVelocityAtArrival    = a.OrbitData.GetVelocityAtEccentricAnomaly(aEccAnomAtDeparture);

            var transitionVeloctyStart = transitionOrbit.GetVelocityAtEccentricAnomaly(eccAnomalyDeparture);
            var transitionVelcityEnd   = transitionOrbit.GetVelocityAtEccentricAnomaly(eccAnomalyArrival);

            var result = new List <Vector3d>();

            result.Add(transitionVeloctyStart - aVelocityAtDeparture);
            result.Add(bVelocityAtArrival - transitionVelcityEnd);
            return(result);
        }
Esempio n. 3
0
        /// <summary>
        /// Find and return referneces to three bodies: self, target and mutual attractor.
        /// Additional attractors chain arrays are used when mutual attractor is not direct parent of target body.
        /// If mutual attractor not existent, or target not assigned, then return empty data.
        /// </summary>
        /// <returns>All references data, or empty data if not found.</returns>
        public BodiesReferencesData GetBodiesReferences()
        {
            if (_orbitMover == null)
            {
                _orbitMover = GetComponent <KeplerOrbitMover>();
            }

            if (_orbitMover == null || Target == null || _orbitMover == Target)
            {
                return(default(BodiesReferencesData));
            }

            List <KeplerOrbitMover> attractorsA = new List <KeplerOrbitMover>();
            List <KeplerOrbitMover> attractorsB = new List <KeplerOrbitMover>();
            double    mass            = 0;
            double    g               = 0;
            Transform mutualAttractor = FindMutualAttractor(
                a: _orbitMover,
                b: Target,
                isGetFullChain: false,
                attractorsAChain: ref attractorsA,
                attractorsBChain: ref attractorsB,
                mass: ref mass,
                gConst: ref g);

            if (mutualAttractor != null)
            {
                return(new BodiesReferencesData()
                {
                    Origin = _orbitMover,
                    Target = Target,
                    Attractor = mutualAttractor,
                    OriginAttractorsChain = attractorsA.ToArray(),
                    TargetAttractorsChain = attractorsB.ToArray(),
                    AttractorMass = mass,
                    GConst = g,
                });
            }

            return(default(BodiesReferencesData));
        }
Esempio n. 4
0
 private void OnEnable()
 {
     _target = target as KeplerOrbitMover;
 }
Esempio n. 5
0
        /// <summary>
        /// Find attractor transform, which is parent for both A and B.
        /// If mutual attractor is not direct parent of both A and B, then look in upper hierarchy of attractors.
        /// </summary>
        /// <param name="a">Body A.</param>
        /// <param name="b">Body B.</param>
        /// <param name="isGetFullChain">If true, attractors chains will include full hierarchy. In opposite case, chains will end before mutual attractor.</param>
        /// <param name="attractorsAChain">Chain of parent attractors for A.</param>
        /// <param name="attractorsBChain">Chain of parent attractors for B.</param>
        /// <param name="gConst">Attractor gravity const.</param>
        /// <param name="mass">Attractor mass.</param>
        /// <returns>Mutual attractor transform or null if not found.</returns>
        /// <remarks>
        /// Chain of attractors is constructed from attractors transforms, which also have own KeplerOrbitMover component.
        ///
        /// Note: this method also retreaving g and mass of attractor. Because these values can be different for any KeplerOrbitMover, those, what belong to body A are preffered.
        /// </remarks>
        public static Transform FindMutualAttractor(KeplerOrbitMover a, KeplerOrbitMover b, bool isGetFullChain, ref List <KeplerOrbitMover> attractorsAChain, ref List <KeplerOrbitMover> attractorsBChain, ref double mass, ref double gConst)
        {
            if (attractorsAChain == null)
            {
                attractorsAChain = new List <KeplerOrbitMover>();
            }
            else
            {
                attractorsAChain.Clear();
            }
            if (attractorsBChain == null)
            {
                attractorsBChain = new List <KeplerOrbitMover>();
            }
            else
            {
                attractorsBChain.Clear();
            }
            int       maxChainLen     = 1000;
            Transform mutualAttractor = null;

            if (a != null && b != null && a != b)
            {
                var attrTransform = a.AttractorSettings.AttractorObject;
                while (attrTransform != null && attractorsAChain.Count < maxChainLen)
                {
                    var attrOrbitMover = attrTransform.GetComponent <KeplerOrbitMover>();
                    attrTransform = null;
                    if (attrOrbitMover != null && !attractorsAChain.Contains(attrOrbitMover))
                    {
                        attrTransform = attrOrbitMover.AttractorSettings.AttractorObject;
                        attractorsAChain.Add(attrOrbitMover);
                    }
                }

                attrTransform = b.AttractorSettings.AttractorObject;
                while (attrTransform != null && attractorsBChain.Count < maxChainLen)
                {
                    var attrOrbitMover = attrTransform.GetComponent <KeplerOrbitMover>();
                    attrTransform = null;
                    if (attrOrbitMover != null && !attractorsBChain.Contains(attrOrbitMover))
                    {
                        attrTransform = attrOrbitMover.AttractorSettings.AttractorObject;
                        attractorsBChain.Add(attrOrbitMover);
                    }
                }

                if (a.AttractorSettings.AttractorObject == b.AttractorSettings.AttractorObject)
                {
                    mutualAttractor = a.AttractorSettings.AttractorObject;
                    gConst          = a.AttractorSettings.GravityConstant;
                    mass            = a.AttractorSettings.AttractorMass;
                }
                else
                {
                    for (int i = 0; i < attractorsAChain.Count && mutualAttractor == null; i++)
                    {
                        for (int n = 0; n < attractorsBChain.Count; n++)
                        {
                            if (attractorsAChain[i].AttractorSettings.AttractorObject == attractorsBChain[n].transform ||
                                attractorsAChain[i].AttractorSettings.AttractorObject == attractorsBChain[i].AttractorSettings.AttractorObject)
                            {
                                mutualAttractor = attractorsAChain[i].AttractorSettings.AttractorObject;
                                gConst          = attractorsAChain[i].AttractorSettings.GravityConstant;
                                mass            = attractorsAChain[i].AttractorSettings.AttractorMass;
                            }
                            else if (attractorsBChain[i].AttractorSettings.AttractorObject == attractorsAChain[i].transform)
                            {
                                mutualAttractor = attractorsBChain[i].AttractorSettings.AttractorObject;
                                gConst          = attractorsAChain[i].AttractorSettings.GravityConstant;
                                mass            = attractorsAChain[i].AttractorSettings.AttractorMass;
                            }
                            else
                            {
                                continue;
                            }
                            break;
                        }
                    }
                }
                if (!isGetFullChain && mutualAttractor != null)
                {
                    int mutualAttractorIndex = -1;
                    for (int i = 0; i < attractorsAChain.Count; i++)
                    {
                        if (attractorsAChain[i].transform == mutualAttractor)
                        {
                            mutualAttractorIndex = i;
                            break;
                        }
                    }
                    if (mutualAttractorIndex >= 0)
                    {
                        //mutualAttractorIndex++;
                        while (attractorsAChain.Count > mutualAttractorIndex)
                        {
                            attractorsAChain.RemoveAt(attractorsAChain.Count - 1);
                        }
                    }
                    mutualAttractorIndex = -1;
                    for (int i = 0; i < attractorsBChain.Count; i++)
                    {
                        if (attractorsBChain[i].transform == mutualAttractor)
                        {
                            mutualAttractorIndex = i;
                            break;
                        }
                    }
                    if (mutualAttractorIndex >= 0)
                    {
                        //mutualAttractorIndex++;
                        while (attractorsBChain.Count > mutualAttractorIndex)
                        {
                            attractorsBChain.RemoveAt(attractorsBChain.Count - 1);
                        }
                    }
                }
                return(mutualAttractor);
            }
            attractorsAChain.Clear();
            attractorsBChain.Clear();
            return(null);
        }
 /// <summary>
 /// Get world space position vector at given time.
 /// </summary>
 /// <param name="target">Target body.</param>
 /// <param name="time">Time, relative to current time.</param>
 /// <param name="attractors">Optional chain of attractors. Order of attractors must be from closest to furthest in hierarchy.</param>
 /// <returns>Position at given time.</returns>
 /// <remarks>
 /// Zero time is considered current state.
 /// For example, at time 0 result position vector will be equal to current target position.
 /// This method allows to progress orbit in time forward (or backward, if passed time is negative) and get position of body at that time.
 /// If attractors collection is not null or empty, then evaluation process will propagate through all attractors, which will affect result.
 /// </remarks>
 public static Vector3 GetPositionAtGivenTime(KeplerOrbitMover target, float time, KeplerOrbitMover[] attractorsChain = null)
 {
     if (target == null)
     {
         return(new Vector3());
     }
     if (!target.OrbitData.IsValidOrbit || target.AttractorSettings.AttractorObject == null)
     {
         return(target.transform.position);
     }
     if (attractorsChain == null || attractorsChain.Length == 0)
     {
         if (!target.enabled || target.TimeScale == 0f)
         {
             return(target.transform.position);
         }
         else
         {
             var finalMeanAnom = target.OrbitData.MeanAnomaly + target.OrbitData.MeanMotion * time;
             var finalEccAnom  = KeplerOrbitUtils.ConvertMeanToEccentricAnomaly(finalMeanAnom, target.OrbitData.Eccentricity);
             var result        = target.AttractorSettings.AttractorObject.transform.position + (Vector3)target.OrbitData.GetFocalPositionAtEccentricAnomaly(finalEccAnom);
             return(result);
         }
     }
     else
     {
         var relativePosition = new Vector3();
         for (int i = 0; i < attractorsChain.Length; i++)
         {
             bool isLast = i == attractorsChain.Length - 1;
             if (attractorsChain[i].OrbitData.IsValidOrbit && attractorsChain[i].AttractorSettings.AttractorObject != null)
             {
                 if (attractorsChain[i].enabled)
                 {
                     var attrMeanAnom = attractorsChain[i].OrbitData.MeanAnomaly + attractorsChain[i].OrbitData.MeanMotion * attractorsChain[i].TimeScale * time;
                     var attrEccAnom  = KeplerOrbitUtils.ConvertMeanToEccentricAnomaly(attrMeanAnom, attractorsChain[i].OrbitData.Eccentricity);
                     relativePosition += (Vector3)attractorsChain[i].OrbitData.GetFocalPositionAtEccentricAnomaly(attrEccAnom);
                 }
                 else
                 {
                     relativePosition += attractorsChain[i].transform.position - attractorsChain[i].AttractorSettings.AttractorObject.transform.position;
                 }
                 if (isLast)
                 {
                     relativePosition += attractorsChain[i].AttractorSettings.AttractorObject.position;
                 }
             }
             else
             {
                 if (isLast || attractorsChain[i].AttractorSettings.AttractorObject == null)
                 {
                     relativePosition += attractorsChain[i].transform.position;
                 }
                 else
                 {
                     relativePosition += (Vector3)attractorsChain[i].OrbitData.Position;
                 }
             }
         }
         if (!target.enabled || target.TimeScale == 0f)
         {
             relativePosition += target.transform.position - target.AttractorSettings.AttractorObject.position;
         }
         else
         {
             var finalMeanAnom = target.OrbitData.MeanAnomaly + target.OrbitData.MeanMotion * time;
             var finalEccAnom  = KeplerOrbitUtils.ConvertMeanToEccentricAnomaly(finalMeanAnom, target.OrbitData.Eccentricity);
             relativePosition += (Vector3)target.OrbitData.GetFocalPositionAtEccentricAnomaly(finalEccAnom);
         }
         return(relativePosition);
     }
 }
 private void Awake()
 {
     _orbitMover = GetComponent <KeplerOrbitMover>();
 }
Esempio n. 8
0
 private void Awake()
 {
     _orbitMover    = GetComponent <KeplerOrbitMover>();
     _spawnNotifier = GetComponent <SpawnNotifier>();
 }
Esempio n. 9
0
 public void NotifyBodySpawned(KeplerOrbitMover b)
 {
     _onGlobalBodySpawnedEvent?.Invoke(b);
 }
Esempio n. 10
0
 private void OnGlobalNotify(KeplerOrbitMover b)
 {
     onBodySpawnedEvent?.Invoke(b);
 }