예제 #1
0
        public IEnumerator CoprocessOdorantCommand()
        {
            yield return(new WaitWhile(delegate() { return !OlfactoryEpithelium.Instanced() || OlfactoryEpithelium.WaitForLoadBalance; }));

            while (!ShouldStop)
            {
                OlfactoryEpithelium.OdorantsProcessingThisFrame++;
                if (!gameObject.activeSelf || !gameObject.activeInHierarchy)
                {
                    yield return(new WaitForSeconds(_suspendSeconds));

                    continue;
                }

                // IsSuspended = true;
                var bounds = new Bounds(Position, localScaleBoxSize);
                if (OlfactoryEpithelium.Get() && !bounds.Contains(OlfactoryEpithelium.Get().Position))
                {
                    yield return(new WaitForSeconds(_suspendSeconds));

                    continue;
                }

                OlfactoryEpithelium.Get().AddOdorantCommand(OdorantCommand);
                yield return(new WaitForSeconds(_suspendSeconds));
            }
        }
        public IEnumerator CoprocessOdorantCommand()
        {
            yield return(new WaitWhile(delegate() { return !OlfactoryEpithelium.Instanced() || OlfactoryEpithelium.WaitForLoadBalance; }));

            while (!ShouldStop)
            {
                OlfactoryEpithelium.OdorantsProcessingThisFrame++;
                if (!gameObject.activeSelf || !gameObject.activeInHierarchy)
                {
                    RemainingSuspendSeconds = OlfactoryEpithelium.Get().BurstUpdateInterval - Time.deltaTime;
                    yield return(new WaitForSeconds(OlfactoryEpithelium.Get().BurstUpdateInterval));

                    continue;
                }

                Vector3 particlePosition;
                int     closestIndex       = -1;
                float   closestSqrDistance = float.MaxValue;
                float   sqrDistance;
                for (var i = 0; i < _numParticles; i++)
                {
                    if (_particleSystem.main.simulationSpace == ParticleSystemSimulationSpace.Local)
                    {
                        particlePosition = transform.localToWorldMatrix.MultiplyPoint(_particles[i].position);
                    }
                    else
                    {
                        particlePosition = _particles[i].position;
                    }

                    sqrDistance = Vector3.SqrMagnitude(particlePosition - OlfactoryEpithelium.Get().Position);
                    if (sqrDistance < OuterRadiusSqrd && sqrDistance < closestSqrDistance)
                    {
                        closestSqrDistance = sqrDistance;
                        closestIndex       = i;
                    }
                }

                if (closestIndex >= 0)
                {
                    if (closestSqrDistance < InnerRadiusSqrd)
                    {
                        OdorantCommand.Intensity = Intensity;
                    }
                    else
                    {
                        var normalizedIntensity = Mathf.Clamp01(_radialScalar.Evaluate((Mathf.Sqrt(closestSqrDistance) - InnerRadius) / (OuterRadius - InnerRadius)));
                        OdorantCommand.Intensity = (byte)Mathf.Lerp(0.0f, Intensity, normalizedIntensity);
                    }

                    OlfactoryEpithelium.Get().AddOdorantCommand(OdorantCommand);
                }

                RemainingSuspendSeconds = OlfactoryEpithelium.Get().BurstUpdateInterval - Time.deltaTime;
                yield return(new WaitForSeconds(OlfactoryEpithelium.Get().BurstUpdateInterval));
            }
        }
예제 #3
0
        public IEnumerator CoprocessOdorantCommand()
        {
            yield return(new WaitWhile(delegate() { return !OlfactoryEpithelium.Instanced() || OlfactoryEpithelium.WaitForLoadBalance; }));

            while (!ShouldStop)
            {
                OlfactoryEpithelium.OdorantsProcessingThisFrame++;
                if (!gameObject.activeSelf || !gameObject.activeInHierarchy)
                {
                    yield return(new WaitForSeconds(OlfactoryEpithelium.Get().BurstUpdateInterval));

                    continue;
                }

                var toOlfactory = OlfactoryEpithelium.Get().Position - Position;

                if (toOlfactory.sqrMagnitude > _odorantVector.sqrMagnitude)
                {
                    yield return(new WaitForSeconds(OlfactoryEpithelium.Get().BurstUpdateInterval));

                    continue;
                }

                var distanceScaler = toOlfactory.magnitude / _odorantVector.magnitude;
                var decayScaler    = 1.0f;

                if (_decaySeconds > 0.0f)
                {
                    decayScaler = DecaySeconds / _decaySeconds;
                }

                var objectAngleToOlfactory = Vector3.Angle(transform.rotation * _odorantVector.normalized, toOlfactory);

                var directionalScaler = 0.0f;

                if (objectAngleToOlfactory < _innerDiffusionAngle)
                {
                    directionalScaler = 1.0f;
                }
                else if (objectAngleToOlfactory < _outerDiffusionAngle)
                {
                    directionalScaler = (_outerDiffusionAngle - Vector3.Angle(transform.rotation * _odorantVector.normalized, toOlfactory)) / (_outerDiffusionAngle - _innerDiffusionAngle);
                }

                OdorantCommand.Intensity = (byte)(_radialScalar.Evaluate(distanceScaler) * decayScaler * directionalScaler * Intensity);

                // Won't add to queue
                OlfactoryEpithelium.Get().AddOdorantCommand(OdorantCommand);

                yield return(new WaitForSeconds(OlfactoryEpithelium.Get().BurstUpdateInterval));
            }
        }
        void OnEnable()
        {
            BurstUpdateInterval = 0.05f;

            if (Instance == this)
            {
                return;
            }

            if (!Instance)
            {
                Instance = this;
            }
            else
            {
                Destroy(this);
                throw new MultipleOlfactoryException("More than one OlfactoryEpithelium constructed.");
            }
        }
        public IEnumerator CoprocessOdorantCommand()
        {
            yield return(new WaitWhile(delegate() { return !OlfactoryEpithelium.Instanced() || OlfactoryEpithelium.WaitForLoadBalance; }));

            while (!ShouldStop)
            {
                OlfactoryEpithelium.OdorantsProcessingThisFrame++;
                if (!gameObject.activeSelf || !gameObject.activeInHierarchy)
                {
                    yield return(new WaitForSeconds(OlfactoryEpithelium.Get().BurstUpdateInterval));

                    continue;
                }

                if (OlfactoryEpithelium.Get())
                {
                    var sqrDistance = Vector3.SqrMagnitude(Position - OlfactoryEpithelium.Get().Position);

                    if (sqrDistance < OuterRadiusSqrd)
                    {
                        if (sqrDistance < InnerRadiusSqrd)
                        {
                            OdorantCommand.Intensity = Intensity;
                        }
                        else
                        {
                            var normalizedIntensity = Mathf.Clamp01(_radialScalar.Evaluate((Mathf.Sqrt(sqrDistance) - InnerRadius) / (OuterRadius - InnerRadius)));
                            OdorantCommand.Intensity = (byte)Mathf.Lerp(0.0f, Intensity, normalizedIntensity);
                        }

                        OlfactoryEpithelium.Get().AddOdorantCommand(OdorantCommand);
                    }
                }
                yield return(new WaitForSeconds(OlfactoryEpithelium.Get().BurstUpdateInterval));
            }
        }
예제 #6
0
        public IEnumerator CoprocessOdorantCommand()
        {
            // Cache position so the odorant stays where it was when Burst was called
            var position = Position;

            yield return(new WaitWhile(delegate() { return !OlfactoryEpithelium.Instanced(); }));

            // This will allow the initial radius to be non-zero
            var startTime = Time.time - OlfactoryEpithelium.Get().BurstUpdateInterval;

            var shouldStop     = false;
            var elapsedSeconds = 0.0f;

            var innerRadius = 0.0f;
            var outerRadius = 0.0f;

            var innerRadiusSquared = 0.0f;
            var outerRadiusSquared = 0.0f;

            var fadeRateSeconds = 1.0f / Mathf.Pow(_effusionRateMetersPerSecond, 0.33333f);
            var fadeScaler      = 1.0f;

            GameObject innerDebugRadius = null;
            GameObject outerDebugRadius = null;

            if (_debugRadius != null)
            {
                innerDebugRadius = Instantiate(_debugRadius, position, Quaternion.identity);
                outerDebugRadius = Instantiate(_debugRadius, position, Quaternion.identity);
            }

            while (!shouldStop)
            {
                // cannot use Time.deltaTime because that's meaningless in a coroutine
                var deltaTime = Time.time - startTime;
                startTime = Time.time;

                OlfactoryEpithelium.OdorantsProcessingThisFrame++;
                if (!gameObject.activeSelf || !gameObject.activeInHierarchy)
                {
                    yield return(new WaitForSeconds(OlfactoryEpithelium.Get().BurstUpdateInterval));

                    continue;
                }

                elapsedSeconds += deltaTime;

                // radius = Mathf.Pow(_diffusivity * elapsedSeconds, 0.33333f);
                outerRadius = _effusionRateMetersPerSecond * elapsedSeconds;
                innerRadius = outerRadius * _impactScaler;

                if (_debugRadius != null)
                {
                    innerDebugRadius.transform.localScale = new Vector3(innerRadius * 2.0f, innerRadius * 2.0f, innerRadius * 2.0f);
                    outerDebugRadius.transform.localScale = new Vector3(outerRadius * 2.0f, outerRadius * 2.0f, outerRadius * 2.0f);
                }

                outerRadiusSquared = outerRadius * outerRadius;
                innerRadiusSquared = innerRadius * innerRadius;

                if (_parentTransform)
                {
                    position = Position;
                    innerDebugRadius.transform.position = position;
                    outerDebugRadius.transform.position = position;
                }

                var sqrDistance = Vector3.SqrMagnitude(position - OlfactoryEpithelium.Get().Position);
                if (sqrDistance < innerRadiusSquared)
                {
                    OdorantCommand.Intensity = (byte)(Intensity * fadeScaler);
                    OlfactoryEpithelium.Get().AddOdorantCommand(OdorantCommand);
                }
                else if (sqrDistance < outerRadiusSquared)
                {
                    var   normalizedDistance = (Mathf.Sqrt(sqrDistance) - innerRadius) / (outerRadius - innerRadius);
                    float userIntensity      = Intensity * fadeScaler * _impactCurve.Evaluate(normalizedDistance);
                    OdorantCommand.Intensity = (byte)userIntensity;
                    OlfactoryEpithelium.Get().AddOdorantCommand(OdorantCommand);
                }

                yield return(new WaitForSeconds(OlfactoryEpithelium.Get().BurstUpdateInterval));

                fadeScaler -= fadeRateSeconds * deltaTime;
                if (fadeScaler <= 0.0f)
                {
                    shouldStop = true;
                }
            }

            if (_debugRadius != null)
            {
                Destroy(innerDebugRadius);
                Destroy(outerDebugRadius);
            }
        }