Пример #1
0
    // Use this for initialization
    void Start()
    {
        if (generateObjects)
        {
            //Validate that the nbody configuration is valid (just requirest initial condition arrays to be same length)
            if ((templateObjects.Length != initialPositions.Length) || (templateObjects.Length != initialVelocities.Length) || (templateObjects.Length != masses.Length))
            {
                Debug.LogError("NBody Simulation Requires that template objects, initial positions, initial velocities, and masses all be the same length.");
                return;
            }

            bodies = new GBody[templateObjects.Length + 1];
            for (int i = 0; i < bodies.Length - 1; i++)
            {
                GameObject renderObject = (GameObject)GameObject.Instantiate(templateObjects[i]);
                renderObject.transform.parent = this.transform;
                bodies[i] = new GBody(initialPositions[i], initialVelocities[i], masses[i], renderObject, renderScale);
            }
            playerGBody = new GBody(playerPrefab.transform.position, Vector3.zero, shipMass, playerPrefab, -1);
            bodies[bodies.Length - 1] = playerGBody;
            forceArray = new Vector3[this.bodies.Length][];
            for (var i = 0; i < this.bodies.Length; i++)
            {
                forceArray[i] = new Vector3[this.bodies.Length];
                for (int j = 0; j < forceArray[i].Length; j++)
                {
                    forceArray[i][j] = Vector3.zero;
                }
            }
        }
    }
Пример #2
0
        /*******************************************************************************/
        /*******************************************************************************/

        public static (GBody, GComment) MCreateProcessInputMethodForTopLevelBackgroundGHS()
        {
            GBody gBody = new GBody(gStatements: new List <string>()
            {
                "#region TBD", " #endregion",
            });
            GComment gComment = new GComment(new List <string>()
            {
                "///  Used to process inputStrings from the ConsoleMonitorPattern"
            });

            return(gBody, gComment);
        }
        public static (IGBody, IGComment) MCreateProcessInputMethodForFileSystemToObjectGraphGHS()
        {
            GBody gBody = new GBody(gStatements: new List <string>()
            {
                "#region TBD", " #endregion",
            });
            GComment gComment = new GComment(new List <string>()
            {
                "///  Used to process inputStrings from the ConsoleMonitorPattern"
            });

            return(gBody, gComment);
        }
        public static IGMethod MCreateExecuteAsyncMethod(string gAccessModifier = "")
        {
            var gMethodDeclaration = new GMethodDeclaration(gName: "ExecuteAsync", gType: "Task",
                                                            gVisibility: "protected", gAccessModifier: gAccessModifier, isConstructor: false,
                                                            gArguments: new Dictionary <IPhilote <IGArgument>, IGArgument>());

            foreach (var kvp in new Dictionary <string, string>()
            {
                { "genericHostsCancellationToken", "CancellationTokenFromCaller " }
            })
            {
                var gMethodArgument = new GArgument(kvp.Key, kvp.Value);
                gMethodDeclaration.GArguments[gMethodArgument.Philote] = gMethodArgument;
            }

            var gBody = new GBody(gStatements: new List <string>()
            {
                "#region Create linkedCancellationSource and linkedCancellationToken",
                "  //// Combine the cancellation tokens,so that either can stop this HostedService",
                "  //linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(internalCancellationToken, externalCancellationToken);",
                "  //var linkedCancellationToken = linkedCancellationTokenSource.Token;",
                "#endregion",
                "#region Register actions with the CancellationTokenFromCaller (s)",
                "  //externalCancellationToken.Register(() => Logger.LogDebug(DebugLocalizer[\"{0} {1} externalCancellationToken has signalled stopping.\"], \"ConsoleMonitorBackgroundService\", \"externalCancellationToken\"));",
                "  //internalCancellationToken.Register(() => Logger.LogDebug(DebugLocalizer[\"{0} {1} internalCancellationToken has signalled stopping.\"], \"ConsoleMonitorBackgroundService\", \"internalCancellationToken\"));",
                "  //linkedCancellationToken.Register(() => Logger.LogDebug(DebugLocalizer[\"{0} {1} linkedCancellationToken has signalled stopping.\"], \"ConsoleMonitorBackgroundService\", \"linkedCancellationToken\"));",
                "#endregion",
                "#region Instantiate this service's Data structure",
                "  //DataInitializationInStartAsyncReplacementPattern",
                "#endregion",
                "// Wait for the conjoined cancellation token (or individually if the hosted service does not define its own internal cts)",
                "// WaitHandle.WaitAny(new[] { linkedCancellationToken.WaitHandle });",
                "Logger.LogDebug(DebugLocalizer[\"{0} {1} ConsoleMonitorBackgroundService is stopping due to \"], \"ConsoleMonitorBackgroundService\", \"ExecuteAsync\"); // add third parameter for internal or external",
                "AssemblyUnitNameReplacementPatternBaseData.Dispose();",
            });
            GComment gComment = new GComment(new List <string>()
            {
                "/// <summary>",
                "/// Called by the genericHost to start the Backgroundservice.",
                "/// Sets up data structures",
                "/// </summary>",
                "/// <param name=\"externalCancellationToken\"></param>",
                "/// <returns></returns>",
            });

            return(new GMethod(gMethodDeclaration, gBody, gComment));
        }
        public static IGMethod MCreateStartAsyncMethod(string gAccessModifier = "")
        {
            var gMethodArguments = new Dictionary <IPhilote <IGArgument>, IGArgument>();

            foreach (var o in new List <IGArgument>()
            {
                new GArgument("genericHostsCancellationToken", "CancellationTokenFromCaller"),
            })
            {
                gMethodArguments.Add(o.Philote, o);
            }
            var gMethodDeclaration = new GMethodDeclaration(gName: "StartAsync", gType: "Task",
                                                            gVisibility: "public", gAccessModifier: gAccessModifier, isConstructor: false,
                                                            gArguments: gMethodArguments);

            var gBody = new GBody(gStatements: new List <string>()
            {
                "#region Create linkedCancellationSource and linkedCancellationToken",
                "  //// Combine the cancellation tokens,so that either can stop this HostedService",
                "  //linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(internalCancellationToken, externalCancellationToken);",
                "  //GenericHostsCancellationToken = genericHostsCancellationToken;",
                "#endregion",
                "#region Register actions with the CancellationTokenFromCaller (s)",
                "  //GenericHostsCancellationToken.Register(() => Logger.LogDebug(DebugLocalizer[\"{0} {1} GenericHostsCancellationToken has signalled stopping.\"], \"FileSystemToObjectGraphService\", \"StartAsync\"));",
                "  //internalCancellationToken.Register(() => Logger.LogDebug(DebugLocalizer[\"{0} {1} internalCancellationToken has signalled stopping.\"], \"FileSystemToObjectGraphService\", \"internalCancellationToken\"));",
                "  //linkedCancellationToken.Register(() => Logger.LogDebug(DebugLocalizer[\"{0} {1} GenericHostsCancellationToken has signalled stopping.\"], \"FileSystemToObjectGraphService\",\"GenericHostsCancellationToken\"));",
                "#endregion",
                "#region Register local event handlers with the IHostApplicationLifetime's events",
                "  // Register the methods defined in this class with the three CancellationTokenFromCaller properties found on the IHostApplicationLifetime instance passed to this class in it's .ctor",
                "  HostApplicationLifetime.ApplicationStarted.Register(OnStarted);",
                "  HostApplicationLifetime.ApplicationStopping.Register(OnStopping);",
                "  HostApplicationLifetime.ApplicationStopped.Register(OnStopped);",
                "#endregion",
                // "DataInitializationInStartAsyncReplacementPattern",
                "//return Task.CompletedTask;"
            });

            GComment gComment = new GComment(new List <string>()
            {
            });
            GMethod newgMethod = new GMethod(gMethodDeclaration, gBody, gComment);

            return(newgMethod);
        }
Пример #6
0
/*******************************************************************************/
/*******************************************************************************/
        static IGClass MCreateStateConfigurationClass(string gVisibility = "public")
        {
//var gMethodArgumentList = new List<IGArgument>() {
//  new GArgument("requestorPhilote", "object"),
//  new GArgument("callback", "object"),
//  new GArgument("timerSignil", "object"),
//  new GArgument("ct", "CancellationTokenFromCaller?")
//};
//var gMethodArguments = new Dictionary<IPhilote<IGArgument>, IGArgument>();
//foreach (var o in gMethodArgumentList) {
//  gMethodArguments.Add(o.Philote, o);
//}
            var gClass    = new GClass("StateConfiguration", gVisibility: gVisibility);
            var gProperty = new GProperty("State", "State", "{get;}", "public");

            gClass.GPropertys.Add(gProperty.Philote, gProperty);
            gProperty = new GProperty("Trigger", "Trigger", "{get;}", "public");
            gClass.GPropertys.Add(gProperty.Philote, gProperty);
            gProperty = new GProperty("NextState", "State", "{get;}", "public");
            gClass.GPropertys.Add(gProperty.Philote, gProperty);
            var gMethodArguments = new Dictionary <IPhilote <IGArgument>, IGArgument>();

            foreach (var o in new List <IGArgument>()
            {
                new GArgument("state", "State"), new GArgument("trigger", "Trigger"), new GArgument("nextState", "State"),
            })
            {
                gMethodArguments.Add(o.Philote, o);
            }
            var gMethodDeclaration = new GMethodDeclaration(gName: "StateConfiguration",
                                                            gVisibility: "public", isConstructor: true,
                                                            gArguments: gMethodArguments);
            var gBody = new GBody(
                gStatements: new List <string>()
            {
                "State=state;", "Trigger=trigger;", "NextState=nextState;",
            });
            var gMethod = new GMethod(gMethodDeclaration, gBody);

            gClass.GMethods.Add(gMethod.Philote, gMethod);
            return(gClass);
        }
Пример #7
0
    public Vector3 calculateForce(GBody body, float gravityDistanceThreshold, float G)  //Simple force calculation function
    //Calculate the changes in x and y direction and distance
    {
        float dx = body.pos.x - this.pos.x;
        float dy = body.pos.y - this.pos.y;
        float dz = body.pos.z - this.pos.z;
        float d  = Mathf.Sqrt(dx * dx + dy * dy + dz * dz);

        //If the distances is too close, do not calculate force (prevents singularities)
        if (d < gravityDistanceThreshold)
        {
            return(new Vector3(0, 0, 0));
        }
        //Create a force vector and return it
        float Fmodified = (this.m * body.m * G) / (d * d * d); //third 'd' is for unit vector

        dx *= Fmodified;
        dy *= Fmodified;
        dz *= Fmodified;
        return(new Vector3(dx, dy, dz));
    }
        public static IGMethod MCreateConvertFileSystemToObjectGraphAsync(IGClass gClass)
        {
            var gMethodArguments = new Dictionary <IPhilote <IGArgument>, IGArgument>();

            foreach (var o in new List <IGArgument>()
            {
                new GArgument("rootString", "string"),
                new GArgument("asyncFileReadBlockSize", "int"),
                new GArgument("enableHash", "bool"),
                new GArgument("convertFileSystemToGraphProgress", "ConvertFileSystemToGraphProgress"),
                new GArgument("Persistence", "Persistence<IInsertResultsAbstract>"),
                new GArgument("PickAndSave", "PickAndSave<IInsertResultsAbstract>"),
                new GArgument("cancellationToken", "CancellationTokenFromCaller?"),
            })
            {
                gMethodArguments.Add(o.Philote, o);
            }
            var gMethodDeclaration = new GMethodDeclaration(gName: "ConvertFileSystemToObjectGraphAsync",
                                                            gType: "Task<ConvertFileSystemToGraphResult>",
                                                            gVisibility: "public", gAccessModifier: "async", isConstructor: false,
                                                            gArguments: gMethodArguments);
            var gBody = new GBody(new List <string>()
            {
                "cancellationToken?.ThrowIfCancellationRequested();",
                "await Task.Delay(10000);",
                "return new ConvertFileSystemToGraphResult();",
            });
            var gComment = new GComment(new List <string>()
            {
                "/// <summary>",
                "/// Convert the contents of a complete FileSystem (or portion thereof) to an Graph representation",
                "/// </summary>",
                "/// <param name=\"\"></param>",
                "/// <param name=\"\"></param>",
                "/// <param name=\"cancellationToken\"></param>",
                "/// <returns>Task<ConvertFileSystemToGraphResult></returns>",
            });

            return(new GMethod(gMethodDeclaration, gBody, gComment));
        }
        public static IGMethod MCreateStopAsyncMethod(string gAccessModifier = "")
        {
            var gMethodDeclaration = new GMethodDeclaration(gName: "StopAsync", gType: "Task",
                                                            gVisibility: "public", gAccessModifier: gAccessModifier, isConstructor: false,
                                                            gArguments: new Dictionary <IPhilote <IGArgument>, IGArgument>());

            foreach (var kvp in new Dictionary <string, string>()
            {
                { "genericHostsCancellationToken", "CancellationTokenFromCaller " }
            })
            {
                var gMethodArgument = new GArgument(kvp.Key, kvp.Value);
                gMethodDeclaration.GArguments[gMethodArgument.Philote] = gMethodArgument;
            }

            var gBody = new GBody(gStatements: new List <string>()
            {
                "// StopAsync issued in both IHostedService and IHostLifetime interfaces",
                "// This IS called when the user closes the ConsoleWindow with the windows top right pane \"x (close)\" icon",
                "// This IS called when the user hits ctrl-C in the console window",
                "//  After Ctrl-C and after this method exits, the Debugger",
                "//   shows an unhandled Exception: System.OperationCanceledException: 'The operation was canceled.'",
                "// See also discussion of Stop async in the following attributions.",
                "// Attribution to  https://stackoverflow.com/questions/51044781/graceful-shutdown-with-generic-host-in-net-core-2-1",
                "// Attribution to https://stackoverflow.com/questions/52915015/how-to-apply-hostoptions-shutdowntimeout-when-configuring-net-core-generic-host for OperationCanceledException notes",
                //Not sure if this is the right place for the dispose
                "// DataDisposalInStopAsyncReplacementPattern",
                "//InternalCancellationTokenSource.Cancel();",
                "// Defer completion promise, until our application has reported it is done.",
                "// return TaskCompletionSource.Task;",
                "//Stop(); // would call the servicebase stop if this was a generic hosted service ??",
                "//return Task.CompletedTask;"
            });
            GComment gComment = new GComment(new List <string>()
            {
            });

            return(new GMethod(gMethodDeclaration, gBody, gComment));
        }
        //public static void MStateMachineFinalizer(
        //  (
        //    IEnumerable<GAssemblyUnit> gAssemblyUnits,
        //    IEnumerable<GCompilationUnit> gCompilationUnits,
        //    IEnumerable<GNamespace> gNamespacess,
        //    IEnumerable<GClass> gClasss,
        //    IEnumerable<GMethod> gMethods) lookupResults) {

        //  MStateMachineFinalizer(lookupResults.gCompilationUnits.First(), lookupResults.gNamespacess.First(),
        //    lookupResults.gClasss.First(), lookupResults.gMethods.First(), finalGStateConfigurations);
        //}
        //public static void MStateMachineFinalizer() {
        //  MStateMachineFinalizer(mCreateAssemblyGroupResult.GTitularBaseCompilationUnit,
        //    mCreateAssemblyGroupResult.GNamespaceBase, mCreateAssemblyGroupResult.GClassBase,
        //    gStateConfiguration: mCreateAssemblyGroupResult.GPrimaryConstructorBase.GStateConfigurations);
        //}
        public static void MStateMachineFinalizer(IGAssemblyGroupBasicConstructorResult mCreateAssemblyGroupResult)
        {
            #region Accumulate the StateConfigurations
            var finalGStateConfiguration = new GStateConfiguration();
            foreach (var gAU in mCreateAssemblyGroupResult.GAssemblyGroup.GAssemblyUnits)
            {
                // finalGStateConfigurations.Add(gAu.GStateConfiguration);
                foreach (var gCU in gAU.Value.GCompilationUnits)
                {
                    // finalGStateConfigurations.Add(gCu.GStateConfiguration);
                    foreach (var gNs in gCU.Value.GNamespaces)
                    {
                        // finalGStateConfigurations.Add(gNs.GStateConfiguration);
                        foreach (var gCl in gNs.Value.GClasss)
                        {
                            // finalGStateConfigurations.Add(gCl.GStateConfiguration);
                            foreach (var gMe in gCl.Value.CombinedMethods())
                            {
                                finalGStateConfiguration.GDOTGraphStatements.AddRange(gMe.GStateConfiguration.GDOTGraphStatements);
                            }
                        }
                    }
                }
            }
            #endregion
            if (finalGStateConfiguration.GDOTGraphStatements.Any())
            {
                //var parsedDiGraph = ParseDiGraphToStateMachine(finalGStateConfiguration);
                ParseDiGraphToStateMachine(finalGStateConfiguration);
                #region StateMachine EnumerationGroups
                var gEnumerationGroup = new GEnumerationGroup(gName: "State and Trigger Enumerations for StateMachine");
                #region State Enumeration
                #region State Enumeration members
                var gEnumerationMemberList = new List <IGEnumerationMember>();
                var enumerationValue       = 1;
                foreach (var name in finalGStateConfiguration.GStateNames)
                {
                    gEnumerationMemberList.Add(LocalizableEnumerationMember(name, enumerationValue++));
                }
                // gEnumerationMemberList = new List<IGEnumerationMember>() {
                //  LocalizableEnumerationMember("WaitingForInitialization",1,"Power-On State - waiting until minimal initialization condition has been met","Waiting For Initialization"),
                //  LocalizableEnumerationMember("InitiateContact",1,"Signal to the Console Monitor that we are a valid ConsoleSource","Initiate Contact"),
                //};
                var gEnumerationMembers = new Dictionary <IPhilote <IGEnumerationMember>, IGEnumerationMember>();
                foreach (var o in gEnumerationMemberList)
                {
                    gEnumerationMembers.Add(o.Philote, o);
                }
                #endregion
                var gEnumeration = new GEnumeration(gName: "State", gVisibility: "public", gInheritance: "",
                                                    gEnumerationMembers: gEnumerationMembers);
                #endregion
                gEnumerationGroup.GEnumerations.Add(gEnumeration.Philote, gEnumeration);
                #region Trigger Enumeration
                #region Trigger Enumeration members
                gEnumerationMemberList = new List <IGEnumerationMember>();
                enumerationValue       = 1;
                foreach (var name in finalGStateConfiguration.GTriggerNames)
                {
                    gEnumerationMemberList.Add(LocalizableEnumerationMember(name, enumerationValue++));
                }
                //gEnumerationMemberList = new List<IGEnumerationMember>() {
                //  LocalizableEnumerationMember("InitializationCompleteReceived",1,"The minimal initialization conditions have been met","Initialization Complete Received"),
                //};
                gEnumerationMembers =
                    new Dictionary <IPhilote <IGEnumerationMember>, IGEnumerationMember
                                    >(); //{gEnumerationMemberList.ForEach(m=>m.Philote,m)};
                foreach (var o in gEnumerationMemberList)
                {
                    gEnumerationMembers.Add(o.Philote, o);
                }
                #endregion
                gEnumeration =
                    new GEnumeration(gName: "Trigger", gVisibility: "public", gInheritance: "",
                                     gEnumerationMembers: gEnumerationMembers);
                gEnumerationGroup.GEnumerations.Add(gEnumeration.Philote, gEnumeration);
                #endregion
                mCreateAssemblyGroupResult.GNamespaceBase.AddEnumerationGroup(gEnumerationGroup);
                #endregion

                //#region StateMachine Transitions Static variable
                //// Add a StaticVariable to the class
                //List<string> gStatements = new List<string>() {"new List<StateConfiguration>(){"};
                //foreach (var sc in parsedDiGraph.StateConfigurations) {
                //  gStatements.Add(sc);
                //}
                //gStatements.Add("}");
                //var gStaticVariable = new GStaticVariable("stateConfigurations", gType: "List<StateConfiguration>",
                //  gBody: new GBody(gStatements));
                //gClass.GStaticVariables.Add(gStaticVariable.Philote, gStaticVariable);
                //#endregion

                #region Create the detailed ConfigureStateMachine Method using the parsedDiGraph information
                // add a method to the class that configures the StateMachine according to the StateConfigurations parsed from the diGraph
                var gMethodGroup = new GMethodGroup(gName: "Detailed ConfigureStateMachine Method");
                var gBody        = new GBody(new List <string>());
                var gMethod      =
                    new GMethod(
                        new GMethodDeclaration(gName: "ConfigureStateMachine", gType: "void", gVisibility: "private",
                                               gAccessModifier: ""), gBody);
                //"// attribution :https://github.com/dhrobbins/ApprovaFlow/blob/master/ApprovaFlow/ApprovaFlow/ApprovaFlow/Workflow/WorkflowProcessor.cs",
                //"// attribution :https://github.com/frederiksen/Stateless-Designer/blob/master/src/StatelessDesigner.VS2017/StatelessCodeGenerator/StatelessCodeGenerator.cs",
                //"// Heavily modified to work in a code generator",
                //"",
                //gBody.GStatements.Add(
                // "#region Delegates for each state's Entry and Exit method calls, and GuardClauses method calls");
                foreach (var stateName in finalGStateConfiguration.GStateNames)
                {
                    gBody.GStatements.Add($"StateMachine.Configure(State.{stateName})");
                    var permittedStateTransitions = finalGStateConfiguration.GDiGraphStates.Where(x => x.state == stateName)
                                                    .Select(x => (triggerName: x.trigger, nextStateName: x.nextstate));
                    foreach (var pST in permittedStateTransitions)
                    {
                        gBody.GStatements.Add($"  .Permit(Trigger.{pST.triggerName},State.{pST.nextStateName})");
                    }
                    gBody.GStatements.Add($";");
                    //    $"public EntryExitDelegate On{stateName}Entry = null;",
                    //    $"public EntryExitDelegate On{stateName}Exit = null;",
                }
                ;
                //}
                //gBody.GStatements.Add("#endregion");
//gBody.GStatements.Add("#region Fluent");
                //foreach (var stateConfiguration in parsedDiGraph.StateConfigurations) {
                //  //gBody.GStatements. Add("StateMachine.Configure($State},");
                //  //  if (true) // stateName == stateConfiguration) {
                //  //    gBody.GStatements.Add($"#endregion");
                //}
                // gBody.GStatements.Add("#endregion");

                //gBody.GStatements.AddRange(
                //  "#region Delegates for each state's Entry and Exit method calls, and GuardClauses method calls",
                //  "#endregion "
                //  );

                //"//  Get a distinct list of states with a trigger from the stateConfigurations static variable",
                //"//  State => Trigger => TargetState",
                //"var states = StateConfigurations.AsQueryable()",
                //".Select(x => x.State)",
                //".Distinct()",
                //".Select(x => x)",
                //".ToList();",
                //"//  Get each trigger for each state",
                //"states.ForEach(state =>{",
                //"var triggers = StateConfigurations.AsQueryable()",
                //".Where(config => config.State == state)",
                //".Select(config => new { Trigger = config.Trigger, TargetState = config.NextState })",
                //".ToList();",
                //"triggers.ForEach(trig => {",
                //"StateMachine.Configure(state).Permit(trig.Trigger, trig.TargetState);",
                //"  });",
                //"});",
                #endregion
                gMethodGroup.GMethods.Add(gMethod.Philote, gMethod);
                mCreateAssemblyGroupResult.GClassBase.GMethodGroups.Add(gMethodGroup.Philote, gMethodGroup);
                #region Add the statement that fires the InitializationCompleteReceived Trigger
                //var statementList = gClass.CombinedMethods().Where(x => x.GDeclaration.GName == "StartAsync").First().GBody
                //  .GStatements;
                //statementList.Insert(statementList.Count - 1, "StateMachine.Fire(Trigger.InitializationCompleteReceived);");
                #endregion
            }
        }
    // Use this for initialization
    void Start()
    {
        //Get the simulation variable
        NBodySimulation[] sims = gameObject.GetComponents <NBodySimulation>();

        if (sims == null)
        {
            Debug.LogWarning("Warning: No NBodySimulation attached to object " + gameObject.name + " which has NBodyDemoMode component; demo will not run.");
            return;
        }

        if (sims.Length != 1)
        {
            Debug.LogWarning("Warning: More than one NBodySimulation attached to object " + gameObject.name + "; using first found.");
        }

        sim = sims[0];

        //Load saved preferences
        if (loadPlayerPrefs)
        {
            LoadPlayerPrefsValues();
        }

        //Generate Body Objects
        GBody[] bodies = new GBody[numberOfBodies];
        for (int i = 0; i < bodies.Length; i++)
        {
            GameObject renderObject;
            if (i == trailsBodyIndex)
            {
                renderObject           = (GameObject)GameObject.Instantiate(trailsObjectPrefab);
                trail                  = (GameObject)GameObject.Instantiate(trailObject);
                trail.transform.parent = renderObject.transform;
                trailsBodyObject       = renderObject;
            }
            else
            {
                renderObject = (GameObject)GameObject.Instantiate(bodyObjectPrefab);
            }
            renderObject.transform.parent = this.transform;
            Vector3 pos = UnityEngine.Random.insideUnitSphere;
            pos.Scale(genRadii);
            Vector3 vel = UnityEngine.Random.insideUnitSphere;
            vel.Scale(genVelocityRange);
            if (perpendicularVelocities)
            {
                vel = new Vector3(pos.z / perpendicularVelocitiesScaling, 0, -pos.x / perpendicularVelocitiesScaling);
            }
            float mass = UnityEngine.Random.Range(genMinMass, genMaxMass);

            bodies[i] = new GBody(pos, vel, mass, renderObject, renderScale);

            if (i == trailsBodyIndex)
            {
                trailsBody = bodies[i];
            }
        }
        sim.SetGBodyObjects(bodies);

        lookCamera.gameObject.AddComponent <SimpleObjectLogger>();
        trailsBodyObject.AddComponent <SimpleObjectLogger>();

        //Configure look response parameters
        startMass  = trailsBody.Mass;
        lookMass   = startMass * massScaling;
        startScale = trailsBodyObject.transform.localScale;
        lookScale  = trailsBodyObject.transform.localScale * sizeScaling;

        //Configure particle emitter
        particles = trailsBodyObject.GetComponent <ParticleSystem>();
        particles.enableEmission = false;

        //Populate UI element components
        progressSlider          = accuracySliderObject.GetComponent <Slider>();
        progressSlider.maxValue = sim.GetGBodyObjects().Length;
        itemsRemainingText      = itemsRemainingTextObject.GetComponent <Text>();
        timerText         = timerTextObject.GetComponent <Text>();
        bestScoreText     = bestScoreTextObject.GetComponent <Text>();
        totalTaskTimeText = totalTaskTimeTextObject.GetComponent <Text>();

        //Initialize High Score UI Component
        bestScoreText.text = "\r\nBest Score\r\n" + bestScore.ToString("F3") + "s";

        //Initialize System State Parameters
        isLooking = false;

        startTime   = DateTime.Now;
        restartTime = DateTime.Now;

        if (PlayerPrefs.HasKey("showTime"))
        {
            bool showTime = PlayerPrefs.GetFloat("showTime") != 0;
            if (!showTime)
            {
                totalTaskTimeTextObject.GetComponent <Text>().enabled = false;
            }
        }
        if (PlayerPrefs.HasKey("taskTime"))
        {
            taskTime = PlayerPrefs.GetFloat("taskTime") * 60;
        }
        totalTaskTimeText.text = taskTime + "s";

        log = gameObject.GetComponent <Logger>();
        log.GenerateLoggableObjectsList();
        log.BeginLogging();
    }
 public Vector3 calculateForce(GBody body, float gravityDistanceThreshold, float G)
 {
     //Simple force calculation function
     //Calculate the changes in x and y direction and distance
     float dx = body.pos.x-this.pos.x;
     float dy = body.pos.y-this.pos.y;
     float dz = body.pos.z-this.pos.z;
     float d = Mathf.Sqrt(dx*dx+dy*dy+dz*dz);
     //If the distances is too close, do not calculate force (prevents singularities)
     if(d<gravityDistanceThreshold) return new Vector3(0,0,0);
     //Create a force vector and return it
     float Fmodified = (this.m*body.m*G)/(d*d*d); //third 'd' is for unit vector
     dx*=Fmodified;
     dy*=Fmodified;
     dz*=Fmodified;
     return new Vector3(dx,dy,dz);
 }
    // Use this for initialization
    void Start()
    {
        //Validate that the nbody configuration is valid (just requirest initial condition arrays to be same length)
        if ((templateObjects.Length != initialPositions.Length) || (templateObjects.Length != initialVelocities.Length) || (templateObjects.Length != masses.Length))
        {
            Debug.LogError("NBody Simulation Requires that template objects, initial positions, initial velocities, and masses all be the same length.");
            return;
        }

        bodies = new GBody[templateObjects.Length + 1];
        for (int i = 0; i < bodies.Length - 1; i++){
            GameObject renderObject = (GameObject)GameObject.Instantiate(templateObjects[i]);
            renderObject.transform.parent = this.transform;
            bodies[i] = new GBody(initialPositions[i], initialVelocities[i], masses[i], renderObject, renderScale);
        }
        playerGBody = new GBody(playerPrefab.transform.position, Vector3.zero, shipMass, playerPrefab, -1);
        bodies[bodies.Length - 1] = playerGBody;
        isValidSimulation = true;
    }