private void copyDescriptionToSliders(EcosystemDescription desc) { float maxForce = 0; float maxRange = 0; float maxSteps = 1; float maxDrag = 0; for (int i = 0; i < desc.speciesData.Length; i++) { for (int j = 0; j < desc.speciesData.Length; j++) { maxForce = Mathf.Max(maxForce, desc.socialData[i, j].socialForce); maxRange = Mathf.Max(maxRange, desc.socialData[i, j].socialRange); } maxSteps = Mathf.Max(maxSteps, desc.speciesData[i].forceSteps + 1); maxDrag = Mathf.Max(maxDrag, desc.speciesData[i].drag); } maxSocialForce = maxForce; maxSocialRange = maxRange; maxForceSteps = Mathf.RoundToInt(maxSteps); dragCenter = maxDrag; particleCount = desc.toSpawn.Count; speciesCount = desc.toSpawn.Query().CountUnique(t => t.species); }
public void RestartSimulation(EcosystemDescription description, ResetBehavior resetBehavior) { if (_restartCoroutine != null) { StopCoroutine(_restartCoroutine); } _restartCoroutine = StartCoroutine(restartCoroutine(description, resetBehavior)); }
static EcosystemDescription() { empty = new EcosystemDescription(isRandomDescription: false) { name = "Empty", socialData = new SocialDescription[0, 0], speciesData = new SpeciesDescription[0], toSpawn = new List <ParticleDescription>() }; }
private void onEcosystemChanged() { _simDescription = simManager.currentDescription; _socialData = simManager.currentDescription.socialData; _effectiveMaxForce = getEffectiveMaxForce(); _effectiveMaxRange = getEffectiveMaxRange(); _numSpecies = (int)(simulatorSetters.GetSpeciesCount()); refreshDisplay(); }
private void restartSimulator(SimulationMethod method, EcosystemDescription ecosystemDescription, ResetBehavior resetBehavior) { switch (method) { case SimulationMethod.InteractionEngine: _ieSimulator.RestartSimulation(ecosystemDescription, resetBehavior); break; case SimulationMethod.Texture: _textureSimulator.RestartSimulation(ecosystemDescription, resetBehavior); break; default: throw new System.InvalidOperationException(); } }
public void NotifyEndedTransition(SimulationMethod method) { isPerformingTransition = false; if (method == _currentSimulationMethod) { switch (method) { case SimulationMethod.Texture: _currentDescription = _textureSimulator.currentDescription; break; case SimulationMethod.InteractionEngine: _currentDescription = _ieSimulator.currentDescription; break; } if (OnEcosystemEndedTransition != null) { OnEcosystemEndedTransition(); } } }
public void RestartSimulation(EcosystemDescription ecosystemDescription, ResetBehavior resetBehavior) { var oldMethod = _currentSimulationMethod; var newMethod = _simulationMethod; _currentSimulationMethod = newMethod; isPerformingTransition = true; if (OnEcosystemBeginTransition != null) { OnEcosystemBeginTransition(); } if (oldMethod != newMethod) { restartSimulator(oldMethod, EcosystemDescription.empty, resetBehavior); restartSimulator(newMethod, ecosystemDescription, resetBehavior); } else { restartSimulator(_currentSimulationMethod, ecosystemDescription, resetBehavior); } }
private IEnumerator restartCoroutine(EcosystemDescription description, ResetBehavior resetBehavior) { if (resetBehavior == ResetBehavior.SmoothTransition || resetBehavior == ResetBehavior.FadeInOut) { yield return(new WaitForSeconds(_manager.resetTime / 2)); } //TODO: remove this and implement everything else resetBehavior = ResetBehavior.ResetPositions; switch (resetBehavior) { case ResetBehavior.None: //If no transition, all we need to do is update the colors foreach (var particle in _particles.Query().Take(MAX_PARTICLES)) { _block.SetColor("_Color", description.speciesData[particle.species].color); particle.GetComponent <Renderer>().SetPropertyBlock(_block); } _manager.NotifyMidTransition(SimulationMethod.InteractionEngine); break; case ResetBehavior.FadeInOut: case ResetBehavior.SmoothTransition: case ResetBehavior.ResetPositions: foreach (var obj in _particles) { DestroyImmediate(obj.gameObject); } _particles.Clear(); foreach (var obj in description.toSpawn.Query().Take(MAX_PARTICLES)) { GameObject particle = Instantiate(_particlePrefab); particle.transform.SetParent(transform); particle.transform.localPosition = obj.position; particle.transform.localRotation = Quaternion.identity; particle.transform.localScale = Vector3.one * _manager.particleRadius; particle.GetComponent <MeshFilter>().sharedMesh = _manager.particleMesh; particle.GetComponent <Renderer>().sharedMaterial = _displayMat; _block.SetColor("_Color", description.speciesData[obj.species].color); particle.GetComponent <Renderer>().SetPropertyBlock(_block); particle.GetComponent <Rigidbody>().velocity = obj.velocity; particle.GetComponent <IEParticle>().species = obj.species; particle.SetActive(true); _particles.Add(particle.GetComponent <IEParticle>()); } TransformBy(_manager.displayAnchor.localToWorldMatrix); _prevDisplayPosition = _manager.displayAnchor.position; _prevDisplayRotation = _manager.displayAnchor.rotation; _prevDisplayScale = _manager.displayAnchor.localScale; _prevParticleSize = _manager.particleRadius; _manager.NotifyMidTransition(SimulationMethod.InteractionEngine); break; default: throw new System.NotImplementedException(); } currentDescription = description; _manager.NotifyEndedTransition(SimulationMethod.InteractionEngine); _restartCoroutine = null; }
public void ApplySliderValues(ref EcosystemDescription currentDescription, out ResetBehavior requiredReset) { requiredReset = ResetBehavior.None; if (particleCount != currentDescription.toSpawn.Count) { requiredReset = ResetBehavior.SmoothTransition; } if (speciesCount != currentDescription.toSpawn.Query().CountUnique(t => t.species)) { requiredReset = ResetBehavior.SmoothTransition; } if (currentDescription.isRandomDescription) { currentDescription = GetRandomEcosystem(currentDescription.name); } else { var preset = (EcosystemPreset)System.Enum.Parse(typeof(EcosystemPreset), currentDescription.name); currentDescription = GetPresetEcosystem(preset, updateSliders: false); float maxForce = float.Epsilon; float maxRange = float.Epsilon; int maxSteps = 0; float maxDrag = float.Epsilon; for (int i = 0; i < currentDescription.speciesData.Length; i++) { for (int j = 0; j < currentDescription.speciesData.Length; j++) { maxForce = Mathf.Max(maxForce, currentDescription.socialData[i, j].socialForce); maxRange = Mathf.Max(maxRange, currentDescription.socialData[i, j].socialRange); } maxSteps = Mathf.Max(maxSteps, currentDescription.speciesData[i].forceSteps); maxDrag = Mathf.Max(maxDrag, currentDescription.speciesData[i].drag); } float forceFactor = maxSocialForce / maxForce; float rangeFactor = maxSocialRange / maxRange; float dragFactor = dragCenter / maxDrag; for (int i = 0; i < currentDescription.speciesData.Length; i++) { for (int j = 0; j < currentDescription.speciesData.Length; j++) { currentDescription.socialData[i, j].socialForce *= forceFactor; currentDescription.socialData[i, j].socialRange *= rangeFactor; } float percent; if (maxSteps == 0) { percent = 1; } else { percent = Mathf.InverseLerp(0, maxSteps, currentDescription.speciesData[i].forceSteps); } int result = Mathf.FloorToInt(Mathf.Lerp(0, maxForceSteps - 1, percent)); currentDescription.speciesData[i].forceSteps = result; currentDescription.speciesData[i].drag *= dragFactor; } } }
public EcosystemDescription GetRandomEcosystemDescription(string seed) { var manager = GetComponentInParent <GeneratorManager>(); EcosystemDescription desc = new EcosystemDescription(isRandomDescription: true) { name = seed, socialData = new SocialDescription[MAX_SPECIES, MAX_SPECIES], speciesData = new SpeciesDescription[MAX_SPECIES], toSpawn = new List <ParticleDescription>() }; //We first generate a bunch of 'meta seeds' which will be used for seeds for //each of the following steps. We do this so that even if the length of the steps //change, it will not have an effect on the results of the following steps. Random.InitState(seed.GetHashCode()); List <int> metaSeeds = new List <int>().Add(() => Random.Range(int.MinValue, int.MaxValue), times: 10); int currMetaSeed = 0; Random.InitState(metaSeeds[currMetaSeed++]); for (int s = 0; s < MAX_SPECIES; s++) { for (int o = 0; o < MAX_SPECIES; o++) { if (o == s) { float socialForce = Random.Range(-manager.maxSocialForce, manager.maxSocialForce); float socialRange; if (socialForce > 0) { socialRange = Random.value * manager.maxSocialRange; } else { socialRange = Random.value * manager.maxSocialRange * manager.maxSelfHateFactor; } desc.socialData[s, o] = new SocialDescription() { socialForce = socialForce, socialRange = socialRange }; } else { desc.socialData[s, o] = new SocialDescription() { socialForce = Random.Range(-manager.maxSocialForce, manager.maxSocialForce), socialRange = Random.value * manager.maxSocialRange }; } } } Random.InitState(metaSeeds[currMetaSeed++]); for (int i = 0; i < MAX_SPECIES; i++) { desc.speciesData[i] = new SpeciesDescription() { drag = Mathf.Clamp01(Random.Range(manager.dragCenter - manager.dragSpread, manager.dragCenter + manager.dragSpread)), forceSteps = Mathf.FloorToInt(Random.Range(0.0f, manager.maxForceSteps)), collisionForce = Random.Range(manager.minCollision, manager.maxCollision) }; } Random.InitState(metaSeeds[currMetaSeed++]); for (int i = 0; i < manager.particleCount; i++) { desc.toSpawn.Add(new ParticleDescription() { position = Random.insideUnitSphere * manager.spawnRadius, velocity = Vector3.zero, species = i % manager.speciesCount }); } Random.InitState(metaSeeds[currMetaSeed++]); var colors = manager.GetRandomColors(); for (int i = 0; i < MAX_SPECIES; i++) { desc.speciesData[i].color = colors[i]; } return(desc); }