protected override JobHandle OnUpdate(JobHandle inputDeps) { var neighbors = new NeighborsDetectionJob { prodThresh = math.cos(math.radians(Bootstrap.Param.neighborFov)), distThresh = Bootstrap.Param.neighborDistance, neighborsFromEntity = GetBufferFromEntity <NeighborsEntityBuffer>(false), positionFromEntity = GetComponentDataFromEntity <Position>(true), entities = group.GetEntityArray(), }; var wall = new WallJob { scale = Bootstrap.Param.wallScale * 0.5f, thresh = Bootstrap.Param.wallDistance, weight = Bootstrap.Param.wallWeight, }; var separation = new SeparationJob { separationWeight = Bootstrap.Param.separationWeight, neighborsFromEntity = GetBufferFromEntity <NeighborsEntityBuffer>(true), positionFromEntity = GetComponentDataFromEntity <Position>(true), }; var alignment = new AlignmentJob { alignmentWeight = Bootstrap.Param.alignmentWeight, neighborsFromEntity = GetBufferFromEntity <NeighborsEntityBuffer>(true), velocityFromEntity = GetComponentDataFromEntity <Velocity>(true), }; var cohesion = new CohesionJob { cohesionWeight = Bootstrap.Param.cohesionWeight, neighborsFromEntity = GetBufferFromEntity <NeighborsEntityBuffer>(true), positionFromEntity = GetComponentDataFromEntity <Position>(true), }; var move = new MoveJob { dt = Time.deltaTime, minSpeed = Bootstrap.Param.minSpeed, maxSpeed = Bootstrap.Param.maxSpeed, }; inputDeps = neighbors.Schedule(this, inputDeps); inputDeps = wall.Schedule(this, inputDeps); inputDeps = separation.Schedule(this, inputDeps); inputDeps = alignment.Schedule(this, inputDeps); inputDeps = cohesion.Schedule(this, inputDeps); inputDeps = move.Schedule(this, inputDeps); return(inputDeps); }
public Tuple <string, string> GetSubmittedSequences(string AlignmentJobID) { AlignmentJob Seq = db.AlignmentJobs.SingleOrDefault(Find => Find.AlignmentID == AlignmentJobID); if (Seq == null) { throw new Exception("Can't Find Alignment Job matches the Given ID"); } string File = Encoding.ASCII.GetString(Seq.ByteText); string FirstSequence = File.Substring(File.IndexOf("First Sequence:") + "First Sequence:".Length, File.IndexOf("Second Sequence:") - "Second Sequence:".Length).Trim(); string SecondSequence = File.Substring(File.IndexOf("Second Sequence:") + "Second Sequence:".Length).Trim(); return(new Tuple <string, string>(FirstSequence, SecondSequence)); }
public async Task <bool> IsFinishedAsync(string AlignmentJobID) { if (string.IsNullOrWhiteSpace(AlignmentJobID)) { throw new Exception("Can't Send Empty string as ID"); } AlignmentJob LocalSequence = await db.AlignmentJobs.SingleOrDefaultAsync(Seq => Seq.AlignmentID == AlignmentJobID); if (LocalSequence == null) { throw new Exception("Can't Find A Record In The Database With The Specified ID"); } else if (!LocalSequence.IsAlignmentCompleted) { return(false); } return(true); }
public bool IsFinished(string AlignmentJobID) { if (string.IsNullOrWhiteSpace(AlignmentJobID)) { throw new Exception("Can't Send Empty string as ID"); } AlignmentJob LocalSequence = db.AlignmentJobs.SingleOrDefault(Seq => Seq.AlignmentID == AlignmentJobID); if (LocalSequence == null) { throw new Exception("Can't Find A Record In The Database With The Specified ID"); } else if (LocalSequence.ByteText == null) { return(false); } return(true); }
public void DeleteAlignmentJob(string AlignmentJobID) { if (string.IsNullOrWhiteSpace(AlignmentJobID)) { throw new Exception("ID Can't be Empty string"); } else { AlignmentJob LocalSequence = db.AlignmentJobs.Find(AlignmentJobID); if (LocalSequence == null) { throw new Exception("Can't Find A Record In The Database With The Specified ID"); } else { db.AlignmentJobs.Remove(LocalSequence); db.SaveChanges(); } } }
public void FinalizeJob(string AlignmentJobID, AlignedSequences AlignmentResult) { if (string.IsNullOrWhiteSpace(AlignmentJobID)) { throw new Exception("ID Can't be Empty string"); } if (AlignmentResult == null) { throw new Exception("Alignment Result Can't be null"); } AlignmentJob Seq = db.AlignmentJobs.SingleOrDefault(Find => Find.AlignmentID == AlignmentJobID); if (Seq == null) { throw new Exception("Can't Find A Record In The Database With The Specified ID"); } Seq.ByteText = GetText(AlignmentResult.StandardFormat(), AlignmentResult.AlignmentScore(DynamicInvoke.GetScoreMatrix(Seq.ScoringMatrix), Seq.GapOpenPenalty, Seq.GapExtensionPenalty), Seq.AlignmentID, Seq.Algorithm, Seq.ScoringMatrix, Seq.Gap, Seq.GapOpenPenalty, Seq.GapExtensionPenalty); db.AlignmentJobs.Update(Seq); db.SaveChanges(); }
public void FinalizeJob(string AlignmentJobID, string AlignmentResult) { if (string.IsNullOrWhiteSpace(AlignmentJobID)) { throw new Exception("ID Can't be Empty string"); } if (AlignmentResult == null) { throw new Exception("Alignment Result Can't be null"); } AlignmentJob Seq = db.AlignmentJobs.SingleOrDefault(Find => Find.AlignmentID == AlignmentJobID); if (Seq == null) { throw new Exception("Can't Find A Record In The Database With The Specified ID"); } Seq.ByteText = GetText(AlignmentResult, Seq.AlignmentID, Seq.Algorithm, Seq.ScoringMatrix, Seq.Gap, Seq.GapOpenPenalty, Seq.GapExtensionPenalty); Seq.IsAlignmentCompleted = true; db.AlignmentJobs.Update(Seq); db.SaveChanges(); }
public async Task DeleteAlignmentJobAsync(string AlignmentJobID) { if (string.IsNullOrWhiteSpace(AlignmentJobID)) { throw new Exception("ID Can't be Empty string"); } else { AlignmentJob LocalSequence = await db.AlignmentJobs.FindAsync(AlignmentJobID); if (LocalSequence == null) { throw new Exception("Can't Find A Record In The Database With The Specified ID"); } else { await Task.Run(() => { db.AlignmentJobs.Remove(LocalSequence); }); await db.SaveChangesAsync(); } } }
void IEcsRunSystem.Run() { if (_filter.EntitiesCount == 0) { return; } if (FullBackground) { if (!CanRead) { jobHandle.Complete(); CanRead = true; } } var neighbors = new NeighborsDetectionJob { prodThresh = NeighborFov, distThresh = NeighborDistance, velocities = BoidEntityData.velocities, positions = BoidEntityData.positions, neighborsFromEntity = BoidEntityData.neighbors, entitiesCount = EntitiesCount }; var wall = new WallJob { scale = WallScale, thresh = WallDistance, weight = WallWeight, positions = BoidEntityData.positions, accelerations = BoidEntityData.accelerations, _right = new Float3(1, 0, 0), _up = new Float3(0, 1, 0), _fwd = new Float3(0, 0, 1), _left = new Float3(-1, 0, 0), _down = new Float3(0, -1, 0), _back = new Float3(0, 0, -1) }; var separation = new SeparationJob { separationWeight = SeparationWeight, entitiesCount = EntitiesCount, neighborsFromEntity = BoidEntityData.neighbors, positions = BoidEntityData.positions, accelerations = BoidEntityData.accelerations }; var alignment = new AlignmentJob { alignmentWeight = AlignmentWeight, entitiesCount = EntitiesCount, neighborsFromEntity = BoidEntityData.neighbors, velocities = BoidEntityData.velocities, accelerations = BoidEntityData.accelerations }; var cohesion = new CohesionJob { cohesionWeight = CohesionWeight, entitiesCount = EntitiesCount, neighborsFromEntity = BoidEntityData.neighbors, positions = BoidEntityData.positions, accelerations = BoidEntityData.accelerations }; var move = new MoveJob { dt = _timeSystem.DeltaTime, minSpeed = MinSpeed, maxSpeed = MaxSpeed, scale = BoidScale, positions = BoidEntityData.positions, velocities = BoidEntityData.velocities, accelerations = BoidEntityData.accelerations, matrices = BoidsVisualisationSystem._nativeMatrices }; jobHandle = neighbors.Schedule(EntitiesCount, NumBoidsPerJob); jobHandle = wall.Schedule(EntitiesCount, NumBoidsPerJob, jobHandle); jobHandle = separation.Schedule(EntitiesCount, NumBoidsPerJob, jobHandle); jobHandle = alignment.Schedule(EntitiesCount, NumBoidsPerJob, jobHandle); jobHandle = cohesion.Schedule(EntitiesCount, NumBoidsPerJob, jobHandle); jobHandle = move.Schedule(EntitiesCount, NumBoidsPerJob, jobHandle); JobHandle.ScheduleBatchedJobs(); if (FullBackground) { CanRead = false; } else { jobHandle.Complete(); CanRead = true; } }
public async Task <string> Align(string FirstSequence, string SecondSequence, string ScoringMatrixName, string Email) { if (string.IsNullOrWhiteSpace(FirstSequence) || string.IsNullOrWhiteSpace(SecondSequence)) { return("Sequence Can't be empty"); } if (FirstSequence.Length > 20000 || SecondSequence.Length > 20000) { return("Sequence length Can't be greater than 20K"); } if (!Regex.IsMatch(FirstSequence, @"^[a-zA-Z]+$") || !Regex.IsMatch(SecondSequence, @"^[a-zA-Z]+$")) { return("Sequence must contains only characters"); } IdentityUser MyUser = await UserManager.FindByEmailAsync(Email); if (MyUser == null) { return("You have to sign-up first to be able to use our alignmnet serive"); } AlignmentJob JobFound = Repo.AreExist(FirstSequence, SecondSequence); if (JobFound == null) { JobFound = new AlignmentJob() { AlignmentID = Guid.NewGuid().ToString(), Algorithm = "ParallelNeedlemanWunsch", ScoringMatrix = ScoringMatrixName.ToUpper(), FirstSequenceHash = Helper.SHA1HashStringForUTF8String(FirstSequence), SecondSequenceHash = Helper.SHA1HashStringForUTF8String(SecondSequence), FirstSequenceName = "Web Service Call", SecondSequenceName = "Web Service Call", GapOpenPenalty = -2, Gap = -8, GapExtensionPenalty = -2 }; SequenceAligner AlgorithmInstance = DynamicInvoke.GetAlgorithm(JobFound.Algorithm); ScoringMatrix ScoringMatrixInstance; try { ScoringMatrixInstance = DynamicInvoke.GetScoreMatrix(JobFound.ScoringMatrix); } catch { return("The Score Matrix Name is invalid."); } string AlignmentResult = string.Empty; float AlignmentScore = 0.0f; await Task.Run(() => { AlignedSequences Result = AlgorithmInstance.Align(FirstSequence, SecondSequence, ScoringMatrixInstance, -8); AlignmentResult = Result.StandardFormat(210); AlignmentScore = Result.AlignmentScore(ScoringMatrixInstance); }); JobFound.ByteText = Helper.GetText(AlignmentResult, AlignmentScore, JobFound.AlignmentID, "ParallelNeedlemanWunsch", ScoringMatrixName, -8, -2, -2); JobFound.UserFK = MyUser.Id; await Repo.AddAlignmentJobAsync(JobFound); return(Encoding.UTF8.GetString(JobFound.ByteText)); } else { return(Encoding.UTF8.GetString(JobFound.ByteText)); } }
public void AddAlignmentJob(AlignmentJob Job) { db.AlignmentJobs.Add(Job); db.SaveChanges(); }
public async Task AddAlignmentJobAsync(AlignmentJob Job) { await db.AlignmentJobs.AddAsync(Job); await db.SaveChangesAsync(); }
public async Task <IActionResult> Align(SequenceViewModel Model, IFormFile FirstFile, IFormFile SecondFile) { if (!string.IsNullOrWhiteSpace(Model.FirstSequence)) { Model.FirstSequence = Model.FirstSequence.Trim().Replace(" ", string.Empty).ToUpper(); } if (!string.IsNullOrWhiteSpace(Model.SecondSequence)) { Model.SecondSequence = Model.SecondSequence.Trim().Replace(" ", string.Empty).ToUpper(); } if (string.IsNullOrWhiteSpace(Model.FirstSequence) && FirstFile != null) { if (FirstFile.ContentType == "text/plain") { string FirstSequence = (await Helper.ConvertFileByteToByteStringAsync(FirstFile)).Trim().Replace(" ", string.Empty).ToUpper(); if (FirstSequence.Length > 10000) { return(RedirectToAction("Grid", "Alignment")); } else if (FirstSequence.Length == 0) { return(View("Error", new ErrorViewModel { Message = "You Can't send a sequence of 0 Length", Solution = "You should send a sequence greater than 0 length" })); } else { Model.FirstSequence = FirstSequence; } } else { return(View("Error", new ErrorViewModel { Message = "You Can't upload a file of any type rather than txt file format", Solution = "You should upload a file of txt file format" })); } } if (string.IsNullOrWhiteSpace(Model.SecondSequence) && SecondFile != null) { if (SecondFile.ContentType == "text/plain") { string SecondSequence = (await Helper.ConvertFileByteToByteStringAsync(SecondFile)).Trim().Replace(" ", string.Empty).ToUpper(); if (SecondSequence.Length > 10000) { return(RedirectToAction("Grid", "Alignment")); } else if (SecondSequence.Length == 0) { return(View("Error", new ErrorViewModel { Message = "You Can't send a sequence of 0 Length", Solution = "You should send a sequence greater than 0 length" })); } else { Model.SecondSequence = SecondSequence; } } else { return(View("Error", new ErrorViewModel { Message = "You Can't upload a file of any type rather than txt file format", Solution = "You should upload a file of txt file format" })); } } if ((Model.FirstSequence == null && FirstFile == null) || (Model.SecondSequence == null && SecondFile == null)) { return(View("Error", new ErrorViewModel { Message = "You Can't enter an empty sequence", Solution = "You have to enter the sequence or either upload a file contains the sequence" })); } if (!Regex.IsMatch(Model.FirstSequence, @"^[a-zA-Z]+$") || !Regex.IsMatch(Model.SecondSequence, @"^[a-zA-Z]+$")) { return(View("Error", new ErrorViewModel { Message = "Your sequence must contains only characters", Solution = "Send sequence contains only characters" })); } AlignmentJob JobFound = Repo.AreExist(Model.FirstSequence, Model.SecondSequence, Model.ScoringMatrix, Model.Gap); if (JobFound == null) { JobFound = new AlignmentJob() { AlignmentID = Guid.NewGuid().ToString(), Algorithm = Model.Algorithm, ScoringMatrix = Model.ScoringMatrix, FirstSequenceHash = Helper.SHA1HashStringForUTF8String(Model.FirstSequence), SecondSequenceHash = Helper.SHA1HashStringForUTF8String(Model.SecondSequence), FirstSequenceName = Model.FirstSequenceName, SecondSequenceName = Model.SecomdSequenceName, GapOpenPenalty = Model.GapOpenPenalty, Gap = Model.Gap, GapExtensionPenalty = Model.GapExtensionPenalty, IsAlignmentCompleted = true, }; SequenceAligner AlgorithmInstance = DynamicInvoke.GetAlgorithm(Model.Algorithm); ScoringMatrix ScoringMatrixInstance = DynamicInvoke.GetScoreMatrix(Model.ScoringMatrix); string AlignmentResult = string.Empty; float AlignmentScore = 0.0f; AlignedSequences Result = AlgorithmInstance.Align(Model.FirstSequence, Model.SecondSequence, ScoringMatrixInstance, Model.Gap); AlignmentResult = Result.StandardFormat(210); AlignmentScore = Result.AlignmentScore(ScoringMatrixInstance); JobFound.ByteText = Helper.GetText(AlignmentResult, AlignmentScore, JobFound.AlignmentID, Model.Algorithm, Model.ScoringMatrix, Model.Gap, Model.GapOpenPenalty, Model.GapExtensionPenalty); JobFound.UserFK = UserManager.GetUserId(User); await Repo.AddAlignmentJobAsync(JobFound); if (Model.DownloadDirectly == 1) { return(File(JobFound.ByteText, "text/plain", $"{JobFound.AlignmentID}_Alignment_Result.txt")); } else { return(RedirectToAction("Display", "Profile", new { AlignmentID = JobFound.AlignmentID })); } } else { if (Model.DownloadDirectly == 1) { return(File(JobFound.ByteText, "text/plain", $"{JobFound.AlignmentID}_Alignment_Result.txt")); } else { return(RedirectToAction("Display", "Profile", new { AlignmentID = JobFound.AlignmentID })); } } }
public async Task <IActionResult> Grid(GridViewModel Model, IFormFile FirstFile, IFormFile SecondFile) { if (Model.FirstSequenceName.Length > 50 || Model.SecomdSequenceName.Length > 50) { return(View("Error", new ErrorViewModel { Message = "You Can't enter a sequence name greater than 50 character", Solution = "You should name your sequence with a name less than or equal to 50 character" })); } if (FirstFile == null || SecondFile == null || FirstFile.ContentType != "text/plain" || SecondFile.ContentType != "text/plain") { return(View("Error", new ErrorViewModel { Message = "You Can't enter an empty File", Solution = "You have to upload a file contains the sequence" })); } string FirstSequence = (await Helper.ConvertFileByteToByteStringAsync(FirstFile)).Trim().Replace(" ", string.Empty).ToUpper(); string SecondSequence = (await Helper.ConvertFileByteToByteStringAsync(SecondFile)).Trim().Replace(" ", string.Empty).ToUpper(); if (!Regex.IsMatch(FirstSequence, @"^[a-zA-Z]+$") || !Regex.IsMatch(SecondSequence, @"^[a-zA-Z]+$")) { return(View("Error", new ErrorViewModel { Message = "Your sequence must contains only characters", Solution = "Send sequence contains only characters" })); } if (FirstSequence.Length <= 10000 || SecondSequence.Length <= 10000) { return(RedirectToAction("Align", "Alignment")); } // Check for earlier exist AlignmentJob SeqFound = Repo.AreExist(FirstSequence, SecondSequence, Model.ScoringMatrix, Model.Gap); if (SeqFound == null) // Means the user didn't submit these sequences before. { string AlignmentID = Guid.NewGuid().ToString(); // Storing in the database await Repo.AddAlignmentJobAsync(new AlignmentJob { AlignmentID = AlignmentID, ScoringMatrix = Model.ScoringMatrix, Algorithm = "Edge", FirstSequenceHash = Helper.SHA1HashStringForUTF8String(FirstSequence), SecondSequenceHash = Helper.SHA1HashStringForUTF8String(SecondSequence), FirstSequenceName = Model.FirstSequenceName, SecondSequenceName = Model.SecomdSequenceName, IsAlignmentCompleted = false, ByteText = Helper.SetTextGrid(FirstSequence, SecondSequence), UserFK = User.FindFirstValue(ClaimTypes.NameIdentifier) }); // Sending to the Grid, that there is a job is required from you // New up instance of SignalR HubConnection with the URL of the SignalR Server Hosting. HubConnection connection = new HubConnection(@"http://mtidna.azurewebsites.net"); // Connect to the Grid SignalR Hub. IHubProxy _hub = connection.CreateHubProxy("GridHub"); // Connecting to the server. await connection.Start(); // Start the connection // await _hub.Invoke("SendToGrid", Newtonsoft.Json.JsonConvert.SerializeObject(new GridInfo { AlignmentJobId = AlignmentID, Email = (await UserManager.FindByIdAsync(Repo.GetAlignmentJobById(AlignmentID).UserFK)).Email })); // Invoke Alignment SignalR Method, and pass the Job Id to the Grid. return(View("Notify", AlignmentID)); } else { if (SeqFound.IsAlignmentCompleted == false) { return(View("Notify", SeqFound.AlignmentID)); // Returning the same Alignment ID } else // the grid already alignment them , so no action is required from the grid, the user can download a text file directly. { return(File(SeqFound.ByteText, "text/plain", $"{SeqFound.AlignmentID}_Clould_Result.txt")); } } }
protected override JobHandle OnUpdate(JobHandle inputDeps) { // Copy entities to the native arrays var ctj = new CopyTransformsToJob() { positions = this.positions, rotations = this.rotations }; var ctjHandle = ctj.Schedule(this, inputDeps); // Count Neigthbours var cnj = new CountNeighboursJob() { positions = this.positions, rotations = this.rotations, neighbours = this.neighbours, maxNeighbours = this.maxNeighbours, neighbourDistance = bootstrap.neighbourDistance }; var cnjHandle = cnj.Schedule(this, ctjHandle); var seperationJob = new SeperationJob() { positions = this.positions, maxNeighbours = this.maxNeighbours, neighbours = this.neighbours, weight = bootstrap.seperationWeight }; var sjHandle = seperationJob.Schedule(this, cnjHandle); var alignmentJob = new AlignmentJob() { positions = this.positions, rotations = this.rotations, maxNeighbours = this.maxNeighbours, neighbours = this.neighbours, weight = bootstrap.alignmentWeight }; var ajHandle = alignmentJob.Schedule(this, sjHandle); var cohesionJob = new CohesionJob() { positions = this.positions, maxNeighbours = this.maxNeighbours, neighbours = this.neighbours, weight = bootstrap.cohesionWeight }; var cjHandle = cohesionJob.Schedule(this, ajHandle); var ran = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, 100000)); var wanderJob = new WanderJob() { dT = Time.deltaTime * bootstrap.speed, random = ran, weight = bootstrap.wanderWeight }; var wjHandle = wanderJob.Schedule(this, cjHandle); var constrainJob = new ConstrainJob() { positions = this.positions, centre = bootstrap.transform.position, radius = bootstrap.radius, weight = bootstrap.constrainWeight }; var constrainHandle = constrainJob.Schedule(this, wjHandle); var fleeJob = new FleeJob() { positions = this.positions, enemyPos = Camera.main.transform.position, distance = bootstrap.fleeDistance, weight = bootstrap.fleeWeight }; var fleeHandle = fleeJob.Schedule(this, constrainHandle); // Integrate the forces var boidJob = new BoidJob() { positions = this.positions, rotations = this.rotations, speeds = this.speeds, dT = Time.deltaTime * bootstrap.speed, damping = 0.01f, banking = 0.00f }; var boidHandle = boidJob.Schedule(this, fleeHandle); // Animate the head and tail var headJob = new HeadJob() { positions = this.positions, rotations = this.rotations, speeds = this.speeds, dT = Time.deltaTime * bootstrap.speed, amplitude = bootstrap.headAmplitude, frequency = bootstrap.animationFrequency, size = bootstrap.size }; var headHandle = headJob.Schedule(this, boidHandle);// Animate the head and tail var tailJob = new TailJob() { positions = this.positions, rotations = this.rotations, speeds = this.speeds, dT = Time.deltaTime * bootstrap.speed, amplitude = bootstrap.tailAmplitude, frequency = bootstrap.animationFrequency, size = bootstrap.size }; var tailHandle = tailJob.Schedule(this, headHandle); // Copy back to the entities var cfj = new CopyTransformsFromJob() { positions = this.positions, rotations = this.rotations }; return(cfj.Schedule(this, tailHandle)); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { Unity.Mathematics.Random ran = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, 100000)); // Copy entities to the native arrays var ctj = new CopyTransformsToJob() { positions = this.positions, rotations = this.rotations }; var ctjHandle = ctj.Schedule(this, inputDeps); cells.Clear(); var partitionJob = new PartitionSpaceJob() { positions = this.positions, cells = this.cells.ToConcurrent(), threedcells = bootstrap.threedcells, cellSize = bootstrap.cellSize, gridSize = bootstrap.gridSize }; var partitionHandle = partitionJob.Schedule(bootstrap.numBoids, 50, ctjHandle); // Count Neigthbours var cnj = new CountNeighboursJob() { positions = this.positions, rotations = this.rotations, neighbours = this.neighbours, maxNeighbours = bootstrap.totalNeighbours, cells = this.cells, cellSize = bootstrap.cellSize, gridSize = bootstrap.gridSize, usePatritioning = bootstrap.usePartitioning, neighbourDistance = bootstrap.neighbourDistance }; var cnjHandle = cnj.Schedule(this, partitionHandle); var seperationJob = new SeperationJob() { positions = SpineSystem.Instance.positions, spineLength = bootstrap.spineLength, spineOffset = bootstrap.spineLength / 2, maxNeighbours = this.maxNeighbours, random = ran, neighbours = this.neighbours, weight = bootstrap.seperationWeight }; var sjHandle = seperationJob.Schedule(this, cnjHandle); var alignmentJob = new AlignmentJob() { positions = this.positions, rotations = this.rotations, maxNeighbours = this.maxNeighbours, neighbours = this.neighbours, weight = bootstrap.alignmentWeight }; var ajHandle = alignmentJob.Schedule(this, sjHandle); var cohesionJob = new CohesionJob() { positions = this.positions, maxNeighbours = this.maxNeighbours, neighbours = this.neighbours, weight = bootstrap.cohesionWeight }; var cjHandle = cohesionJob.Schedule(this, ajHandle); var wanderJob = new WanderJob() { dT = Time.deltaTime * bootstrap.speed, random = ran, weight = bootstrap.wanderWeight }; var wjHandle = wanderJob.Schedule(this, cjHandle); var constrainJob = new ConstrainJob() { positions = this.positions, centre = bootstrap.constrainPosition, radius = bootstrap.radius, weight = bootstrap.constrainWeight }; var constrainHandle = constrainJob.Schedule(this, wjHandle); var fleeJob = new FleeJob() { positions = this.positions, enemyPos = Camera.main.transform.position, distance = bootstrap.fleeDistance, weight = bootstrap.fleeWeight }; var fleeHandle = fleeJob.Schedule(this, constrainHandle); var seekJob = new SeekJob() { positions = this.positions, targetPos = Camera.main.transform.position, weight = bootstrap.seekWeight }; var seekHandle = seekJob.Schedule(this, fleeHandle); // Integrate the forces var boidJob = new BoidJob() { positions = this.positions, rotations = this.rotations, speeds = this.speeds, dT = Time.deltaTime * bootstrap.speed, damping = 0.01f, limitUpAndDown = bootstrap.limitUpAndDown, banking = 0.01f }; var boidHandle = boidJob.Schedule(this, seekHandle); // Copy back to the entities var cfj = new CopyTransformsFromJob() { positions = this.positions, rotations = this.rotations }; return(cfj.Schedule(this, boidHandle)); }