Ejemplo n.º 1
0
        /// <summary>
        /// Create a list of Channels, using the mesh hierarchy to get the visible frames representing the channels,
        /// and the gene or the physiology to get the species-specific parameters such as chemical selectivity
        /// </summary>
        /// <param name="gene"></param>
        /// <returns></returns>
        private Channel[] LoadChannels(Gene gene)
        {
            // Read any channels defined by the gene
            Channel[] channel = gene.GetChannels();

            // If none are defined, create some and load with the default chemical#s from the cell type
            if (channel.Length == 0)
            {
                ChannelData[] chanData = physiology.GetChannelData();					// read the default src, dst, chem
                if (chanData != null)
                {
                    channel = new Channel[chanData.GetLength(0)];						// create enough channels
                    for (int c = 0; c < channel.Length; c++)							// copy in the default chemical selectivity
                    {
                        channel[c] = new Channel();
                        channel[c].chemical = chanData[c].Chemical;
                        channel[c].constant = chanData[c].Constant;                     // and default for user-definable constant
                    }
                }
            }

            //// Get a list of the "chan#" frames (visible organelles), in order, then copy to the channels
            //JointFrame[] channelFrame = null;
            //try
            //{
            //    channelFrame = JointFrame.IndexFrameType(rootFrame, JointFrame.FrameType.Channel);
            //    for (int c = 0; c < channel.Length; c++)
            //    {
            //        channel[c].organelle = channelFrame[c];
            //    }
            //}
            //catch
            //{
            //    throw new SDKException(this.name + " has different numbers of channels in the cell type ("
            //                            + channel.Length + ") and the mesh (" + channelFrame.Length + ")");
            //}

            return channel;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Get a clone of this Cell from the library, loading it first if necessary
        /// </summary>
        /// <returns>A modifiable clone of the named Cell</returns>
        /// <param name="gene">The gene containing the cell's properties, orientation and wiring</param>
        /// <param name="owner">The organism that owns me</param>
        public static Cell Get(Gene gene, Organism owner)
        {
            Cell cell = null;

            // Get name of the cell from the gene
            string fullname = gene.XFile();

            // if the library already contains a Cell of that name, that's what we'll clone from
            if (library.ContainsKey(fullname))
            {
                cell = (Cell)library[fullname];
            //				Debug.WriteLine("	Cell: Created new Cell instance: "+name+":"+cell.instance);
            }
            // otherwise, create a new entry in the library by loading a whole X file
            else
            {
                cell = new Cell(fullname);
            //				Debug.WriteLine("	Cell: Created new Cell archetype: "+name+":"+cell.instance);
            }

            // Return a cloned instance of this Cell
            Cell newCell = cell.Clone(gene, owner);

            newCell.CreateBoundMarker();								// temp: create marker to show bounding sphere

            return newCell;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Given the gene that has/would be used to create this cell, update its parameters
        /// to reflect the current wiring setup, etc. Then recurse through children and siblings
        /// until the whole tree has been constructed
        /// </summary>
        /// <param name="gene"></param>
        public void UpdateGene(Gene gene)
        {
            // The gene type is our cell type, which we get from ToString()
            gene.Type = physiology.ToString();

            // Create a new list of channels from the user-defined wiring
            gene.Channels = new List<Channel>();
            gene.Channels.AddRange(channel);

            // Get our current plug orientation matrix
            gene.Orientation = PlugOrientation;

            // Get the name of our parent socket (if we're not the root)
            if (parentSocket != null)
            {
                gene.Socket = parentSocket.Name.Substring(0,4);					// convert "skt3-0" to skt3
            }
            // Recursively build up the rest of the genome...
            // If we have a child, create a new gene for it, link it into the genome tree and ask the child to update this gene
            if (this.firstChild != null)
            {
                gene.FirstChild = new Gene();
                this.firstChild.UpdateGene(gene.FirstChild);
            }
            // If we have a sibling, blah blah blah
            if (this.sibling != null)
            {
                gene.Sibling = new Gene();
                this.sibling.UpdateGene(gene.Sibling);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Clone this cell
        /// </summary>
        /// <param name="gene">The gene specifying this cell instance's orientation, wiring, etc.</param>
        /// <param name="owner">The organism that owns me</param>
        private Cell Clone(Gene gene, Organism owner)
        {
            // Make a shallow copy of all members
            Cell newCell = (Cell)this.MemberwiseClone();

            // Replace members that are CLONED copies of objects in the master...
            newCell.rootFrame = JointFrame.CloneHierarchy(rootFrame);	// my unique copy of the frame hierarchy
            // TODO: Clone any other members here

            // Replace or create members that are UNIQUE to this instance...
            newCell.instance = instance++;													// my instance number (tally in master)
            newCell.PlugOrientation = gene.Orientation;										// my orientation in the parent socket
            newCell.owner = owner;															// my owning organism

            newCell.joint = JointFrame.IndexFrameType(
                            newCell.rootFrame,JointFrame.FrameType.Animating);				// lists of my animation, hotspot & skt frames
            newCell.hotspot = JointFrame.IndexFrameType(
                            newCell.rootFrame, JointFrame.FrameType.Hotspot);
            newCell.socket = JointFrame.IndexFrameType(
                            newCell.rootFrame, JointFrame.FrameType.Socket);

            newCell.physiology = Physiology.LoadPhysiology(newCell.group, newCell.name, newCell.variantName,		// my Physiology class containing functionality
                                                            newCell,
                                                            newCell.joint.Length,
                                                            newCell.socket.Length);

            newCell.GetMyVariantIndex();                                                    // Convert variant name into an index before trying to access channel data

            newCell.channel = newCell.LoadChannels(gene);									// lists of channel info from gene AND mesh frames

            newCell.collisionFrames = new List<JointFrame>();
            newCell.GetMeshFrames(newCell.rootFrame, newCell.collisionFrames, false);		// a list of mesh-containing frames for collision tests

            // Set all the internal (organelle) frames to invisible, because they aren't normally rendered
            newCell.HideOrganelles();

            // TODO: Initialise other instance-specific members here

            // Now that everything is set up, call the Physiology subclass's Init() method to allow the physiology to initialise itself
            newCell.physiology.Init();

            // Add a device reset handler to rebuild this cell's resources
            Engine.Device.DeviceReset += new System.EventHandler(newCell.OnReset);

            return newCell;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Recursively walk the gene tree, extract the Cell filenames, clone the Cell from the library and
        /// record their interconnections (root->joint)
        /// </summary>
        /// <param name="gene">the gene being expressed</param>
        /// <param name="parent">the Cell that is the parent of this new one</param>
        /// <returns>the Cell created by this gene</returns>
        private Cell GetCells(Gene gene, Cell parent)
        {
            // Get the X filename from the gene and either load or fetch that Cell from the library,
            Cell s = Cell.Get(gene, this);

            // Add it to the flat partlist
            partList[numParts++] = s;

            // Locate this cell's SOCKET by locating the frame with the correct name in the
            // parent (if any)
            if (parent!=null)
                s.Attach(parent, gene.Socket);

            // if the gene has any siblings, recursively attach their structures as siblings of this one
            if (gene.Sibling!=null)
                s.Sibling = GetCells(gene.Sibling, parent);					// we share a parent

            // if the gene has a child, recursively attach this as the child of this one
            if (gene.FirstChild!=null)
                s.FirstChild = GetCells(gene.FirstChild, s);				// I am the parent

            return s;														// return the new Cell to the parent/sibling
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Add a cell of the selected type to the creature at the selected socket (if any)
        /// </summary>
        public void Add(string name)
        {
            // If no socket is selected, quit
            if (Lab.SelectedSocket == null) return;

            // If the selected socket already has a cell attached to it, we mustn't add another!
            if (SelectedSocketIsOccupied())
                return;

            // OK to add
            try
            {
                Gene gene = new Gene(name);												// Create a gene for the cell type
                Cell newCell = Cell.Get(gene, Lab.SelectedOrg);							// create a cell from the gene

                if (Lab.SelectedCell.FirstChild == null)								// if the selected cell has no children
                    Lab.SelectedCell.FirstChild = newCell;								// attach the new cell to it as the first child
                else																	// otherwise, drop to the first child and find its last
                {																		// sibling. The new cell becomes the youngest sibling
                    Cell sib = Lab.SelectedCell.FirstChild;
                    while (sib.Sibling != null)
                        sib = sib.Sibling;
                    sib.Sibling = newCell;
                }

                newCell.Attach(Lab.SelectedCell, Lab.SelectedSocket);					// record the cell's .parent and .parentSocket

                Refresh();																// update org's part list, channels, etc.

                Lab.SelectedCell = newCell;												// Select the cell we've just added
                newCell.SelectFirst();													// and the first socket on that cell

            }
            catch (Exception e)
            {
                throw new SDKException("Unable to create new cell of selected type: " + name, e);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Read genome from XML stream
        /// </summary>
        /// <param name="xml"></param>
        private void Read(XmlTextReader xml)
        {
            string tag = "";

            while (xml.Read())												// for each node in the file...
            {
                if (xml.NodeType == XmlNodeType.Element)					// <tag> rather than final </document>
                {
                    switch (xml.Name)										// depending on tag...
                    {
                        case "gene":										// <gene> the ROOT gene </gene>
                            root = Gene.RecursiveRead(xml,null);			// read recursively to support part hierarchy
                            break;
                            // Any other root level tags go here

                            // anything else must be a data tag, so wait for its text to arrive
                        default:
                            tag = xml.Name;
                            break;
                    }

                }
                    // text within tags
                else if (xml.NodeType == XmlNodeType.Text)
                {
                    switch (tag)
                    {
                            // data tags relating to the Genome as a whole (not a gene) go here
                        default:
                            throw new XmlException("unexpected tag type: "+tag);
                    }
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Print an entire genome's hierarchy to the debug output stream
        /// </summary>
        /// <param name="root">root of hierarchy</param>
        /// <param name="level">current depth into hierarchy (set this to 0)</param>
        /// <returns></returns>
        public static void DebugHierarchy(Gene root, int level)
        {
            // set up an indent level
            string indent = "";
            for (int i=0; i<level; i++)
                indent += "\t";

            Debug.WriteLine(indent+"*** GENE ["+root.Type+"] ***");
            Debug.WriteLine(indent+"    Socket: ["+root.Socket+"]");

            // continue walking the tree
            if (root.FirstChild!=null)
            {
                DebugHierarchy(root.FirstChild, level+1);
            }
            if (root.Sibling!=null)
            {
                DebugHierarchy(root.Sibling, level);
            }
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Create a minimal genome for building a new creature.
 /// The genome consists of a single gene defining a CORE cell
 /// </summary>
 public Genome()
 {
     root = new Gene("Core");
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Recurse through a genome writing the genes to an XML file
        /// </summary>
        /// <param name="xml">The output stream</param>
        /// <param name="gene">The gene to write (and then descend into)</param>
        public static void RecursiveWrite(XmlWriter xml, Gene gene)
        {
            xml.WriteStartElement("gene");
            xml.WriteElementString("type", gene.Type);
            if (gene.Socket!=null)
                xml.WriteElementString("socket", gene.Socket);
            xml.WriteElementString("orientation", EncodeMatrix(gene.Orientation));

            // Write <channel> nodes
            foreach (Channel c in gene.Channels)
            {
                c.WriteXml(xml);
            }

            // If this gene has children, nest them inside
            if (gene.FirstChild != null)
                RecursiveWrite(xml, gene.FirstChild);

            // Close the </gene>
            xml.WriteEndElement();

            // If this gene has siblings, write them at the same level
            if (gene.Sibling != null)
                RecursiveWrite(xml, gene.Sibling);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Read this <gene></gene> and any nested genes too
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="previous">previous SIBLING of the gene being created</param>
        /// <returns></returns>
        public static Gene RecursiveRead(XmlTextReader xml, Gene previous)
        {
            Gene gene = null;
            Gene elder = null;
            string tag = "";

            while (xml.Read())												// for each node...
            {
                // <tag>
                if (xml.NodeType == XmlNodeType.Element)
                {
                    // Handle the tag
                    switch (xml.Name)										// depending on tag...
                    {
                            // A child gene definition is nested inside this one, so create it recursively
                        case "gene":
                            // the first such gene is the child of this one
                            if (gene.FirstChild==null)
                            {
                                gene.FirstChild = RecursiveRead(xml,null);
                                elder = gene.FirstChild;
                            }
                            // subsequent genes are siblings of each other
                            else
                            {
                                elder.Sibling = RecursiveRead(xml,null);
                                elder = elder.Sibling;
                            }
                            break;

                        // A channel
                        case "channel":
                            gene.Channels.Add(ReadChannel(xml));
                            break;

                            // anything else must be a standalone <tag>text</tag>, so wait for its text to arrive
                        default:
                            tag = xml.Name;
                            break;
                    }

                }
                // text within tags
                else if (xml.NodeType == XmlNodeType.Text)
                {
                    switch (tag)			// action depends on the tag this text is part of
                    {
                            // create the named gene as a sibling of the previous one
                        case "type":										// <type> this gene's type </type>
                            gene = new Gene();								// start a new gene
                            gene.Type = xml.Value;							// store its type name
                            break;
                            // <attachment>
                        case "socket":
                            gene.Socket = xml.Value;
                            break;
                            // <position>
                        case "orientation":
                            gene.Orientation = ReadMatrix(xml.Value);
                            break;

                            // Other gene initialisers here

                        default:
                            throw new XmlException("unexpected gene tag type: "+tag);
                    }
                }
                // closing tag
                else if (xml.NodeType == XmlNodeType.EndElement)
                {
                    if (xml.Name == "gene")
                    {
                        return gene;										// return the gene I just created
                    }
                }
            }

            throw new XmlException("missing </gene> tag");					// should always return before end of file
        }