示例#1
0
        /// <summary> We've been sent a Stimulus. 
        /// Handle it if possible, or hand it on to our physiology for handling</summary>
        /// <param name="stimulus">The stimulus information</param>
        /// <returns>Return true if the stimulus was handled</returns>
        public bool ReceiveStimulus(Stimulus stim)
        {
            // Stimuli that should be handled by ALL cells in a receiving organism go here...
            switch (stim.Type)
            {
                    // TODO: Add universal stimulus cases here, then return true
                case "dummy":
                    return true;

            }

            // If that doesn't work, test to see if this cell is actually in range of the sender,
            // and attempt to handle such stimuli (e.g. being stung or eaten)
            if (AbsSphere.IsPenetrating(new Sphere(stim.TransmitterLocn, stim.TransmissionRange))==false)
                return false;

            // Stimuli that should be handled by cells directly affected go here...
            switch (stim.Type)
            {
                    // TODO: Add stimulus cases here, then return true
                case "dummy":
                    return true;

            }

            // If that doesn't work, pass the stimulus on to our Physiology to see if our cell type
            // can handle it. This allows the stimulus types to be extended
            return (physiology.ReceiveStimulus(stim));
        }
示例#2
0
        /// <summary> We've been sent a Stimulus. 
        /// <param name="stimulus">The stimulus information</param>
        /// <returns>Return true if the stimulus was handled</returns>
        public bool ReceiveStimulus(Stimulus stim)
        {
            switch (stim.Type)
            {
                // Stimuli that we know how to handle...

                // TODO: Add stimulus cases here, and return true
                case "dummy":
                    break;
            }
            return false;
        }
示例#3
0
        /// <summary> We've been sent a Stimulus. 
        /// Handle it if possible, or hand it on to one of our cells for handling</summary>
        /// <param name="stimulus">The stimulus information</param>
        /// <returns>Return true if the stimulus was handled by one or more cells</returns>
        public bool ReceiveStimulus(Stimulus stim)
        {
            bool handled = false;
            switch (stim.Type)
            {
                    // Stimuli that we know how to handle...

                    // TODO: Add organism-wide stimulus cases here, and set handled=true

                    // Those we don't know how to handle we send on to all our cells
                    // (the cells then check whether the stimulus was intended for them, by
                    // seeing if their spheres intersect the transmission range)
                default:
                    foreach (Cell c in partList)
                    {
                        if (c.ReceiveStimulus(stim)==true)
                            handled = true;
                    }
                    break;
            }
            return handled;
        }
示例#4
0
        /// <summary>
        /// Given a stimulus, find out how that object is positioned relative to a given hotspot on this cell. 
        /// Cell types use this to establish how much notice they should take of an incoming stimulus (passive sensing). 
        /// Call methods on the returned SensorItem to calculate the angle and/or distance as required.
        /// </summary>
        /// <param name="spot">Which hotspot to use</param>
        /// <param name="range">Current range of hotspot</param>
        /// <param name="stim">the stimulus we received</param>
        public SensorItem TestStimulusVisibility(int spot, float range, Stimulus stim)
        {
            // Get a matrix that will convert target location into hotspot-relative coordinates
            // Create a matrix that will rotate objects into a sensor-relative frame
            Matrix transform = hotspot[spot].CombinedMatrix;
            transform.Invert();

            // transform the source position into sensor-relative coordinates
            Vector3 relpos = Vector3.TransformCoordinate(stim.TransmitterLocn, transform);

            // Return a SensorItem with this info (the SensorItem.Object refers to the sender)
            return new SensorItem(stim.From, relpos);
        }
示例#5
0
        /// <summary>
        /// Common stimulus: Emit a transient sound. (Call repeatedly for continuous noise)
        /// Any cell can call this - we don't need an effector hotspot.
        /// Recipients ("ear" celltypes) should combine .TransmissionRange with distance from source to compute perceived loudness
        /// First parameter of Stimulus is the pitch
        /// NOTE: CameraShips' root cell types will receive the stimuli and can use the parameters to emit a real (DirectSound) sound to the user
        /// </summary>
        /// <param name="range">Distance sound travels</param>
        /// <param name="pitch">Frequency of sound, for pitch-sensitive or pitch-selective sensors: 0 = low, 1.0 = high</param>
        /// <param name="timbre">Optional string for the DirectSound file that should be played if this sound is picked up by the current CameraShip</param>
        protected void Sound(float range, float pitch, string timbre)
        {
            // Create the stimulus
            Stimulus stimulus = new Stimulus((IDetectable)owner, ((IDetectable)owner).ReqLocation(), range, "sound", pitch, timbre, null, null);

            // Send it to each organism in range
            SensorItem[] recipients = owner.GetObjectsInRange(-1, range, true, false, false);
            foreach (SensorItem recipient in recipients)
            {
                recipient.Object.ReceiveStimulus(stimulus);
            }
        }
示例#6
0
        /// <summary> We've been sent a Stimulus that our basic Cell object doesn't understand.
        /// This overload responds to the "bioluminescence" stimulus
        /// Parameter 0 will be a ColorValue containing the bioluminescent cell's current anim colour
        /// <param name="stimulus">The stimulus information</param>
        /// <returns>Return true if the stimulus was handled</returns>
        public override bool ReceiveStimulus(Stimulus stim)
        {
            float direction = 0.5f;
            float intensity = 0f;

            if (stim.Type == "bioluminescence")
            {
                // Find out if the sender is within range of our hotspots
                SensorItem cone0 = owner.TestStimulusVisibility(0, range, stim);
                float dist = cone0.Distance();                                                      // dist will be roughly the same from both hotspots
                if (dist < range)                                                                   // if object is within range...
                {
                    // Find out how visible it is from each hotspot
                    SensorItem cone1 = owner.TestStimulusVisibility(1, range, stim);                // now we know we're in range, get the other hotspot's visibility
                    float angle0 = cone0.Angle();                                                   // Get angle from each hotspot
                    float angle1 = cone1.Angle();
                    if ((angle0 < halfAngle)||(angle1 < halfAngle))                                 // if within sight of at least one hotspot...
                    {
                        // Compare the light to our filter colour
                        ColorValue light = (ColorValue)stim.Param0;                                 // Stimulus param 0 will be the bioluminescent cell's current anim colour
                        float r1 = light.Red - r;                                                   // difference in RGB between filter and cell
                        float g1 = light.Green - g;
                        float b1 = light.Blue - b;
                        float match = 1f - (float)Math.Sqrt((r1 * r1 + g1 * g1 + b1 * b1) / 3f);   // least squares measure of similarity (1=identical)

                        // calc intensity and direction, if we match spectrally
                        if (match > 0.8f)                                                           // <=1/2 is a bad match, e.g. rgB doesn't match rGb but they're still a third similar!
                        {                                                                           // only give a direction response to a good match
                            // Scale signal according to distance downrange
                            intensity = cone0.Distance(range);

                            // compute direction
                            float a0 = 1f - angle0 / halfAngle;
                            float a1 = 1f - angle1 / halfAngle;
                            direction = (a1 - a0) / 2f + 0.5f;
                            if (focusDirection < 0f) focusDirection = 0f;
                            else if (focusDirection > 1f) focusDirection = 1f;
                        }

                        // If this stimulus comes from a different source to our present focus of attention
                        // ignore it unless it is stronger (in which case, shift attention to it)
                        if ((stim.From != focusObject)                                              // Is this object different from our present focus of attention
                            && (intensity < focusIntensity))                                        // and weaker?
                            return true;                                                            // ignore it

                        focusObject = stim.From;                                                    // Shift attention if necessary (if found stronger source)
                        focusIntensity = intensity;                                                 // record the new signal strength
                        focusDirection = direction;
                        lossOfSignal = LOSSOFSIGNALAFTER;                                           // and reset the loss-of-signal timers
                        fading = false;

                        // Calculate the signal entering each sensor
                        if (angle0 < halfAngle)                                                     // if the source is visible from sensor0
                            signal0 = intensity * (1f - angle0 / halfAngle);                        // scale signal by deviation from sensor's midline
                        if (angle1 < halfAngle)                                                     // otherwise leave as zero
                            signal1 = intensity * (1f - angle1 / halfAngle);                        // Repeat for sensor1

                        SetOutputs();                                                               // Write the two cell outputs

                        }
                }
                return true;
            }
            return false;
        }
示例#7
0
        /// <summary>
        /// Emit a specialised broadcast stimulus (other than sounds, disturbances, etc.)
        /// </summary>
        /// <param name="type">Stimulus type, e.g. "sound"</param>
        /// <param name="hotspot">hotspot emitting stimulus, or -1 to emit from the cell's axis</param>
        /// <param name="range">distance over which stimulus travels</param>
        /// <param name="angle">cone of transmission - half-angle from hotspot or cell's normal</param>
        /// <param name="param0">first stimulus param (type-dependent)</param>
        /// <param name="param1"></param>
        /// <param name="param2"></param>
        /// <param name="param3"></param>
        protected void EmitStimulus(string type, int hotspot, float range, float angle, Object param0, Object param1, Object param2, Object param3)
        {
            // Create the stimulus
            Stimulus stimulus = new Stimulus((IDetectable)owner, ((IDetectable)owner).ReqLocation(), range, type, param0, param1, param2, param3);

            // Send it to each organism in range along the cone of transmission
            SensorItem[] recipients = owner.GetObjectsInRange(hotspot, range, true, false, false);
            foreach (SensorItem recipient in recipients)
            {
                if (recipient.Angle() <= angle)
                    recipient.Object.ReceiveStimulus(stimulus);
            }
        }
示例#8
0
        /// <summary>
        /// Common stimulus: Emit an omnidirectional ripple of water disturbance, to show that a cell has radically changed shape.
        /// Use when a muscle twitches rapidly, jaws clench, etc. Whole-body movements should be detected passively; this is just a shockwave in the water
        /// that can be picked up by a hairy cell, like the lateral line in fish.
        /// Usually best called from a SlowUpdate() whenever the cell (e.g. its JointOutput) has changed more than a certain amount since the last update.
        /// Note: the sub engines could emit disturbances, which could scare away creatures
        /// </summary>
        /// <param name="range">The intensity of the stimulus and hence its range</param>
        protected void Disturbance(float range)
        {
            Stimulus stimulus = new Stimulus((IDetectable)owner, ((IDetectable)owner).ReqLocation(), range, "disturbance", null, null, null, null);

            SensorItem[] recipients = owner.GetObjectsInRange(-1, range, true, false, false);
            foreach (SensorItem recipient in recipients)
            {
                recipient.Object.ReceiveStimulus(stimulus);
            }
        }
示例#9
0
 /// <summary> We've been sent a Stimulus that our basic Cell object doesn't understand.
 /// Override this method to handle any stimuli that our particular cell type understands. 
 /// This mechanism allows new cell types to declare new stimulus types. Note however that 
 /// existing cell types won't have any handlers for these new stimuli. (On the other hand
 /// it's possible to define handlers in advance of any cell types that know how to emit a 
 /// particular stimulus, making them "stimulus-ready"!)
 /// <param name="stimulus">The stimulus information</param>
 /// <returns>Return true if the stimulus was handled</returns>
 public virtual bool ReceiveStimulus(Stimulus stim)
 {
     return false;
 }
示例#10
0
        public override bool ReceiveStimulus(Stimulus stim)
        {
            switch (stim.Type)
            {
                // Potentially picked up a disturbance
                case "disturbance":
                    SensorItem result = owner.TestStimulusVisibility(0, range, stim);                       // see if the source is within our acceptance angle
                    if (result.Angle()<HALFANGLE)
                    {
                        Output(0,result.Distance(range));                                                   // if so, output a signal as a fraction of the source range
                    }
                    return true;
            }

            Output(0,0);                                                                                    // if no valid sensation, clear the signal
            return false;
        }
示例#11
0
        /// <summary> We've been sent a Stimulus that our basic Cell object doesn't understand.
        /// This overload responds to the "bioluminescence" stimulus
        /// Parameter 0 will be a ColorValue containing the bioluminescent cell's current anim colour
        /// <param name="stimulus">The stimulus information</param>
        /// <returns>Return true if the stimulus was handled</returns>
        public override bool ReceiveStimulus(Stimulus stim)
        {
            if (stim.Type == "bioluminescence")
            {
                // Find out if the sender is within range/sight of our hotspot
                SensorItem sender = owner.TestStimulusVisibility(0, range, stim);
                float dist = sender.Distance();
                if (dist<range)
                {
                    float angle = sender.Angle();
                    if (angle < halfAngle)
                    {
                        // Parameter 0 will be a ColorValue containing the bioluminescent cell's current anim colour
                        ColorValue light = (ColorValue)stim.Param0;

                        // Compare the light to our filter colour
                        float r1 = light.Red - r;                                                   // difference in RGB between filter and cell
                        float g1 = light.Green - g;
                        float b1 = light.Blue - b;
                        float signal = 1f - (float)Math.Sqrt((r1 * r1 + g1 * g1 + b1 * b1) / 3f);   // least squares measure of similarity (1=identical)
                        signal *= 1f - angle / halfAngle;                                           // scale by deviation from mid-line (so objects straight ahead have more effect)

                        // NOTE: Removed this because bioluminescent cells are obviously tiny at long range
                        //float apparentSize = sender.AngleSubtended();                               // scale by angle subtended (depends on size and distance)
                        //if (apparentSize < 0) apparentSize = 0;
                        //signal *= apparentSize;

                        // Add this signal to that waiting for inclusion in the output
                        incoming += signal;
                    }
                }
                return true;
            }
            else return false;
        }