public static void GrowNewBranches(ParallelQuery <Module> allModules) { // SelectMany will join all of the new modules returned by each module (if any) into a single list allModules.SelectMany(module => { return(module.nodes // Grow module off of it if not grown and vigor is greater than vigorRootMins .Where(node => node.main == null && node.lateral == null && node.v > module.plant.plantConfig.vigorRootMin) .Select(node => { UnityEngine.Debug.Log("Growing new branch at pos " + Node.GetGlobalPos(node)); float lambda = module.plant.plantConfig.lambda; float dPrime = module.root.v * module.plant.plantConfig.D / module.plant.plantConfig.vigorRootMax; ModulePrototype closestPrototype = PlantConfig.ClosestPrototype(module.plant.plantConfig, lambda, dPrime); Module newModule = ModulePrototype.CreateInstance(module.plant, closestPrototype, Node.GetPose(node)); node.main = newModule.root; // connect main to root so the trickle of q and v can work properly newModule.root.parent = node.main; return newModule; })); }) // Do last piece not in parallel, since we are appending to lists that is not thread safe .ToList() .ForEach(newModule => { newModule.plant.modules.Add(newModule); }); }
public Plant(PlantConfig plantConfig, ModulePrototype startModule, Pose rootPose) { this.plantConfig = plantConfig; this.root = ModulePrototype.CreateInstance(this, startModule, rootPose); this.modules = new List <Module>(); this.modules.Add(this.root); }
public static float SquaredDist(ModulePrototype prototype, float lambda, float D) { float dLambda = lambda - prototype.lambda; float dD = D - prototype.lambda; return(dLambda * dLambda + dD * dD); }
public static ModulePrototype ClosestPrototype(PlantConfig plantConfig, float lambda, float D) { if (plantConfig.modulePrototypes == null) { throw new System.ArgumentNullException("plantConfig.modulePrototypes"); } return(plantConfig.modulePrototypes.MinBy(modulePrototype => ModulePrototype.SquaredDist(modulePrototype, lambda, D))); }
public static Module CreateInstance(Plant plant, ModulePrototype module, Pose pose) { // Make a copy of all the nodes module.nodes.ForEach(node => { node.copyOfMe = Node.MemberwiseClone(node); }); // Assign references of the copies to the copied elements List <Node> copiedNodes = Enumerable.ToList( Enumerable.Select(module.nodes, (node => { node.copyOfMe.parent = GetCopyOfMeIfNotNull(node.parent); node.copyOfMe.main = GetCopyOfMeIfNotNull(node.main); node.copyOfMe.lateral = GetCopyOfMeIfNotNull(node.lateral); return(node.copyOfMe); }))); Module result = new Module(plant, module.root.copyOfMe, copiedNodes, pose); result.nodes.ForEach(node => { node.module = result; }); return(result); }