예제 #1
0
    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);
    }
예제 #2
0
 public void RestartSimulation(EcosystemDescription description, ResetBehavior resetBehavior)
 {
     if (_restartCoroutine != null)
     {
         StopCoroutine(_restartCoroutine);
     }
     _restartCoroutine = StartCoroutine(restartCoroutine(description, resetBehavior));
 }
예제 #3
0
 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();
    }
예제 #5
0
    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();
        }
    }
예제 #6
0
    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();
            }
        }
    }
예제 #7
0
    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);
        }
    }
예제 #8
0
    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;
    }
예제 #9
0
    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;
            }
        }
    }
예제 #10
0
    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);
    }