/// <summary>
 ///		Returns true if the given scene node is a child
 ///		of this node.
 /// </summary>
 /// <param name="child">Scene node to look for.</param>
 public bool ChildExists(SceneNode child)
 {
     return _childList.Contains(child);
 }
 /// <summary>
 ///		Adds the given scene node to this nodes child list.
 /// </summary>	
 /// <param name="child">Scene node to add as child.</param>
 public virtual void AddChild(SceneNode child)
 {
     if (_childList.Contains(child)) return;
     _childList.Add(child);
     child.Parent = this;
     SceneGraph.AttachNode(child);
 }
 /// <summary>
 ///		Moves the given child to the front of the rendering list.
 /// </summary>
 /// <param name="child">Child to move.</param>
 public void BringChildToFront(SceneNode child)
 {
     _childList.Remove(child);
     _childList.Add(child);
 }
 /// <summary>
 ///     Initializes a new instance of this class.
 /// </summary>
 /// <param name="node">Node that was transformed.</param>
 /// <param name="originalTransformation">Nodes original transformation.</param>
 /// <param name="newTransformation">Nodes new transformation.</param>
 public TransformNodeUndoOperation(SceneNode node, Transformation originalTransformation, Transformation newTransformation)
 {
     _node = node;
     _newTransformation = newTransformation;
     _originalTransformation = originalTransformation;
 }
        /// <summary>
        ///		Saves the given node and all of its children into a given binary writer.
        /// </summary>
        /// <param name="writer">Binary writer to save the given node into.</param>
        /// <param name="node">Node to save into binary writer.</param>
        private void SaveNode(BinaryWriter writer, SceneNode node)
        {
            // Write in the name of this node.
            writer.Write(node.GetType().FullName);

            // Save the nodes details into the stream.
            node.Save(writer);

            // Save the children.
            writer.Write(node.Children.Count);
            foreach (SceneNode childNode in node.Children)
                SaveNode(writer, childNode);
        }
 /// <summary>
 ///		Removes the given scene node from this nodes child list.
 /// </summary>
 /// <param name="child">Scene node to remove.</param>
 public virtual void RemoveChild(SceneNode child)
 {
     _childList.Remove(child);
     child.Parent = null;
     SceneGraph.DetachNode(child);
 }
Example #7
0
        /// <summary>
        ///		Loads this map from a given object or file path.
        /// </summary>
        /// <param name="url">Url of file to open map from.	</param>
        /// <param name="password">If a password is required to open this map, this will be used.</param>
        /// <param name="baseNode">The base node that all loading should be started from, this allows you to ignore this node and any nodes higher in the graph like the Root Camera.</param>
        /// <param name="keepPersistent">If set to true persistent ob jects will be kept.</param>
        /// <param name="keepCameras">If set to true all cameras will not be destroyed.</param>
        public void Load(object url, string password, SceneNode baseNode, bool keepPersistent, bool keepCameras)
        {
            // Keep track of the url.
            if (url is string)
                _url = url as string;

            // Try and open a stream to the file.
            Stream stream = StreamFactory.RequestStream(url, StreamMode.Open);
            if (stream == null) return;
            BinaryReader reader = new BinaryReader(stream);

            // Check the header of this file to make sure it really is a Fusion map file.
            if (reader.ReadChar() != 'F' || reader.ReadChar() != 'M' || reader.ReadChar() != 'P')
                throw new Exception("Fusion map file has invalid header, file may be corrupt.");

            // Read in the bit mask explaining the header.
            int headerBitMask = reader.ReadByte();
            if ((headerBitMask & 4) != 0) _mapProperties.Name = reader.ReadString();
            if ((headerBitMask & 8) != 0) _mapProperties.Author = reader.ReadString();
            if ((headerBitMask & 16) != 0) _mapProperties.Description = reader.ReadString();
            if ((headerBitMask & 32) != 0) _mapProperties.Version = reader.ReadSingle();

            // Read in the rest of the file into memory so we can decompress / decrypt it.
            byte[] fileData = reader.ReadBytes((int)(stream.Length - stream.Position));

            // Decrypt the data if required.
            if ((headerBitMask & 2) != 0)
                fileData = DataMethods.Decrypt(fileData, password);

            // Decompress the data if required.
            if ((headerBitMask & 1) != 0)
                fileData = DataMethods.Inflate(fileData);

            // Create a memory stream and a binary reader so we can minipulate the data better.
            MemoryStream memStream = new MemoryStream(fileData, 0, fileData.Length);
            BinaryReader memStreamReader = new BinaryReader(memStream);

            // Read in the encryption header to make sure everything went correctly.
            if ((headerBitMask & 2) != 0 || (headerBitMask & 1) != 0)
                if (memStreamReader.ReadChar() != 'C' || memStreamReader.ReadChar() != 'H' || memStreamReader.ReadChar() != 'K')
                    throw new Exception("Unable to open Fusion map file, password is invalid or fils is corrupted.");

            // Read in the tileset pool used to render tilemap segments.
            int tilesetCount = memStreamReader.ReadByte();
            Tileset.TilesetPool.Clear();
            for (int i = 0; i < tilesetCount; i++)
            {
                if (memStreamReader.ReadBoolean() == true)
                {
                    string newTilesetUrl = memStreamReader.ReadString();

                    if (newTilesetUrl.ToString().ToLower().StartsWith("pak@"))
                        newTilesetUrl = newTilesetUrl.ToString().Substring(4); // Legacy support.

                    if (Runtime.Resources.ResourceManager.ResourceIsCached(newTilesetUrl))
                        Tileset.AddToTilesetPool(Runtime.Resources.ResourceManager.RetrieveResource(newTilesetUrl) as Tileset);
                    else
                    {
                        Runtime.Debug.DebugLogger.WriteLog("Loading tileset from " + newTilesetUrl);
                        Tileset newTileset = new Tileset();
                        newTileset.Load(newTilesetUrl);
                        Tileset.AddToTilesetPool(newTileset);
                        Runtime.Resources.ResourceManager.CacheResource(newTilesetUrl, newTileset);
                    }

                }
            }

            // Tell the scene graph to load itself from this memory stream.
            _sceneGraph.Load(memStreamReader, keepPersistent, keepCameras, baseNode);

            // Free up the memory stream and reader.
            memStream.Close();
            memStream = null;

            // Free up the reader and stream.
            stream.Close();
            stream = null;

            // Reclaim memory used during loading.
            GC.Collect();
        }
 /// <summary>
 ///		Clear out every scene node from this scene graph.
 /// </summary>
 public void Clear()
 {
     _rootNode.ClearChildren();
     _rootNode = new SceneNode("Root");
     _cameraList.Clear();
 }
        /// <summary>
        ///		Loads the scene graph from a given binary reader.
        /// </summary>
        /// <param name="stream">Binary reader to load this scene graph from.</param>
        /// <param name="baseNode">The base node that all loading should be started from, this allows you to ignore this node and any nodes higher in the graph like the Root Camera.</param>
        /// <param name="keepPersistent">If set to true persistent ob jects will be kept.</param>
        /// <param name="keepCameras">If set to true all cameras will not be destroyed.</param>
        public void Load(BinaryReader reader, bool keepPersistent, bool keepCameras, SceneNode baseNode)
        {
            // Dispose of all old entities.

                // Lets compile a list of all peristent nodes if we are keeping them.
                ArrayList persistentList = new ArrayList();
                if (keepPersistent == true)
                {
                    ArrayList entityList = new ArrayList(_nodeList);
                    foreach (SceneNode node in entityList)
                        if (node.IsPersistent == true)
                            persistentList.Add(node);
                        else
                            node.Dispose();
                    entityList.Clear();
                    entityList = null;
                }

            // Get starting memory.
            long startingMemory = GC.GetTotalMemory(true);

            // Clear out any non-persistent cameras.
            if (keepCameras == false)
            {
                ArrayList removalList = new ArrayList();

                foreach (CameraNode camera in _cameraList)
                    if (camera.IsPersistent == false)
                        removalList.Add(camera);

                foreach (CameraNode camera in removalList)
                    _cameraList.Remove(camera);
            }

            // Reset unique ID counter.
            _uniqueIDTracker = 0;

            // Clean out base node.
            if (baseNode != null)
                baseNode.ClearChildren();
            else
                _rootNode.ClearChildren();

            bool baseNodeExists = reader.ReadBoolean();
            if (baseNodeExists == true)
            {
                int childCount = reader.ReadInt32();
                for(int i = 0; i < childCount; i++)
                {
                    if (baseNode != null)
                        baseNode.AddChild(LoadNode(reader));
                    else
                        _rootNode.AddChild(LoadNode(reader));
                }
            }
            else
                _rootNode = LoadNode(reader, true);

            // Lets see if we can reattached any persistent nodes, if not lets just
            // tack them onto the root node.
            if (keepPersistent == true)
            {
                foreach (SceneNode node in persistentList)
                {
                    if (node.Parent == null || node.Parent.IsPersistent == false)
                        (baseNode == null ? _rootNode : baseNode).AddChild(node);
                }
            }

            // Say how many have been created.
            DebugLogger.WriteLog("Loaded " + _uniqueIDTracker + " nodes into scene graph, with a cumulative memory allocation of " + (((GC.GetTotalMemory(true) - startingMemory) / 1024.0f) / 1024.0f) + "mb.");

            // Go through each node and grab its properties
            SyncronizeNodes();

            // Reset loading percentage.
            _loadingProgress = 0;
        }
 /// <summary>
 ///		Adds a node from the global node list.
 /// </summary>
 /// <param name="node">Node to add to global node list.</param>
 public static void AttachNode(SceneNode node)
 {
     if (_nodeList.Contains(node)) return;
     _nodeList.Add(node);
 }
 /// <summary>
 ///		Removes a node from the global node list.
 /// </summary>
 /// <param name="node">Node to remove to global node list.</param>
 public static void DetachNode(SceneNode node)
 {
     _nodeList.Remove(node);
 }
 /// <summary>
 ///		Moves the given child 1 step forewards in the rendering list.
 /// </summary>
 /// <param name="child">Child to move.</param>
 public void ShiftChildForewards(SceneNode child)
 {
     int index = _childList.IndexOf(child);
     _childList.Remove(child);
     _childList.Insert(Math.Min(_childList.Count, index + 1), child);
 }
 /// <summary>
 ///		Moves the given child 1 step backwards in the rendering list.
 /// </summary>
 /// <param name="child">Child to move.</param>
 public void ShiftChildBackwards(SceneNode child)
 {
     int index = _childList.IndexOf(child);
     _childList.Remove(child);
     _childList.Insert(Math.Max(0, index - 1), child);
 }
 /// <summary>
 ///		Moves the given child to the back of the rendering list.
 /// </summary>
 /// <param name="child">Child to move.</param>
 public void SendChildToBack(SceneNode child)
 {
     _childList.Remove(child);
     _childList.Insert(0, child);
 }
 /// <summary>
 ///		Copys all the data contained in this scene node to another scene node.
 /// </summary>
 /// <param name="node">Scene node to copy data into.</param>
 public virtual void CopyTo(SceneNode node)
 {
 }
 /// <summary>
 ///		Saves this scene graph into a given binary writer.
 /// </summary>
 /// <param name="stream">Binary writer to save this scene graph into.</param>
 /// <param name="baseNode">The base node that all saving should be started from, this allows you to ignore this node and any nodes higher in the graph like the Root Camera.</param>
 public void Save(BinaryWriter writer, SceneNode baseNode)
 {
     writer.Write(baseNode != null);
     if (baseNode != null)
     {
         writer.Write(baseNode.Children.Count);
         foreach (SceneNode childNode in baseNode.Children)
             SaveNode(writer, childNode);
     }
     else
         SaveNode(writer, _rootNode);
 }
        /// <summary>
        ///     Responsable for removing references of this object and deallocated
        ///     resources that have been allocated.
        /// </summary>
        public virtual void Dispose()
        {
            // Clear out references
            if (_parent != null)
                _parent.RemoveChild(this);
            _parent = null;
            SceneGraph.DetachNode(this);

            // Remove all the childrens references. (Don't tell them to dispose, that is done elsewhere).
            ClearChildren();

            // Remove all the script references.
            VirtualMachine.GlobalInstance.RemoveReferences(this);

            Statistics.StoreInt("Disposal Counted Scene Node Count", Statistics.ReadInt("Disposal Counted Scene Node Count") - 1);
        }
 /// <summary>
 ///		Used by the EnumerateNodes function to add all the children of
 ///		a node to the given array list.
 /// </summary>
 /// <param name="nodeList">Array list to add children to.</param>
 /// <param name="node">Node to add children from.</param>
 private void EnumerateChildrenOfNode(ArrayList nodeList, SceneNode node)
 {
     nodeList.AddRange(node.Children);
     for (int i = 0; i < node.Children.Count; i++)
         EnumerateChildrenOfNode(nodeList, (SceneNode)node.Children[i]);
 }
 /// <summary>
 ///		Fills the scene graph tree view with the given scene node and its child nodes.
 /// </summary>
 /// <param name="node">Node to add to scene graph.</param>
 /// <param name="collection">Collection to add node to.</param>
 private void FillSceneGraph(SceneNode node, TreeNodeCollection collection)
 {
     foreach (SceneNode subNode in node.Children)
     {
         TreeNode treeNode = new TreeNode((subNode.Name == null ? "Untitled" : subNode.Name) + "("+subNode.Transformation.X+","+subNode.Transformation.Y+","+subNode.Transformation.Z+")");
         collection.Add(treeNode);
         _nodeHashTable.Add(treeNode, subNode);
         FillSceneGraph(subNode, treeNode.Nodes);
     }
 }
        /// <summary>
        ///		Loads the next node in the given binary reader and returns it.
        /// </summary>
        /// <param name="reader">Binary reader to read node from.</param>
        /// <param name="getProgress">If set to true this node is used to judge the current progress.</param>
        /// <returns>Scene node that was loaded from the binary reader.</returns>
        private SceneNode LoadNode(BinaryReader reader, bool getProgress)
        {
            // Read in the name of this node's class.
            string name = reader.ReadString();

            //HighPreformanceTimer timer = new HighPreformanceTimer();

            // Create a new instance of this entity and tell it to load itself.
            // (See if its a known object first as its quicker to get it without reflection)
            SceneNode node = null;
            if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.entitynode"))
                node = new EntityNode();
            else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.scriptedentitynode"))
                node = new ScriptedEntityNode();
            else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.scenenode"))
                node = new SceneNode();
            else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.groupnode"))
                node = new GroupNode();
            else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.emitternode"))
                node = new EmitterNode();
            else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.tilemapsegmentnode"))
                node = new TilemapSegmentNode();
            else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.pathmarkernode"))
                node = new PathMarkerNode();
            else if (name.ToLower().EndsWith("binaryphoenix.fusion.engine.entitys.tilenode"))
                node = new TileNode();
            else
                node = (SceneNode)ReflectionMethods.CreateObject(name);

            //DebugLogger.WriteLog("Created scene graph node " + name + " in " + timer.DurationMillisecond + ".\n");
            //timer.Restart();

            // Load in this nodes details.
            node.UniqueID = (_uniqueIDTracker++);
            node.Load(reader);

            //DebugLogger.WriteLog("Loaded scene graph node " + name + " in " + timer.DurationMillisecond + ".\n");

            // Read in all the children of this node, and attach
            // them to this node.
            DebugLogger.IncreaseIndent();
            int childCount = reader.ReadInt32();
            for (int i = 0; i < childCount; i++)
            {
                SceneNode childNode = LoadNode(reader);
                node.AddChild(childNode);

                if (getProgress == true)
                    _loadingProgress = (int)(((float)(i + 1) / (float)childCount) * 100.0f);
            }
            DebugLogger.DecreaseIndent();

            return node;
        }
Example #21
0
        /// <summary>
        ///		Saves this map into the given file you pass.
        /// </summary>
        /// <param name="url">Url of file to save map to.</param>
        /// <param name="baseNode">The base node that all saving should be started from, this allows you to ignore this node and any nodes higher in the graph like the Root Camera.</param>
        public void Save(object url, SceneNode baseNode)
        {
            // Try and open a stream to the file.
            Stream stream = StreamFactory.RequestStream(url, StreamMode.Truncate);
            if (stream == null) return;
            BinaryWriter writer = new BinaryWriter(stream);

            // Write in the magic number (Always FMP).
            writer.Write(new char[] { 'F', 'M', 'P' });

            // Write in the file header.
            byte stateHeader = 0;
            if (_mapProperties.Compress == true) stateHeader |= 1;
            if (_mapProperties.Encrypt == true)  stateHeader |= 2;
            if (_mapProperties.Name != null) stateHeader |= 4;
            if (_mapProperties.Author != null) stateHeader |= 8;
            if (_mapProperties.Description != null) stateHeader |= 16;
            if (_mapProperties.Version != 0) stateHeader |= 32;
            writer.Write(stateHeader);
            if (_mapProperties.Name != null) writer.Write(_mapProperties.Name);
            if (_mapProperties.Author != null) writer.Write(_mapProperties.Author);
            if (_mapProperties.Description != null) writer.Write(_mapProperties.Description);
            if (_mapProperties.Version != 0) writer.Write(_mapProperties.Version);

            // Create a new memory stream to write main data into.
            MemoryStream memStream = new MemoryStream();
            BinaryWriter memStreamWriter = new BinaryWriter(memStream);

            // Write in a encryption / compression checker.
            if (_mapProperties.Compress == true || (_mapProperties.Encrypt && _mapProperties.Password != ""))
                memStreamWriter.Write(new char[] { 'C', 'H', 'K' });

            // Save in the tileset pool used to render tilemap segments.
            memStreamWriter.Write((byte)Tileset.TilesetPool.Count);
            foreach (Tileset tileset in Tileset.TilesetPool)
            {
                memStreamWriter.Write(tileset.Url is string);
                if (tileset.Url is string) memStreamWriter.Write((string)tileset.Url);
            }

            // Tell the scene graph to save itself into the stream.
            _sceneGraph.Save(memStreamWriter, baseNode);

            // Close the memory stream.
            byte[] buffer = memStream.ToArray();
            memStreamWriter.Close();
            memStream.Close();

            // Compress the data if required.
            if (_mapProperties.Compress == true)
                buffer = DataMethods.Deflate(buffer);

            // Encrypt the data if required.
            if (_mapProperties.Encrypt == true && _mapProperties.Password != "")
                buffer = DataMethods.Encrypt(buffer, _mapProperties.Password);

            // Write main data into main stream.
            writer.Write(buffer, 0, buffer.Length);

            // Sweep up the dirt.
            writer.Close();
        }
 /// <summary>
 ///     Initializes a new instance of this class.
 /// </summary>
 /// <param name="nodes">Nodes that were inserted.</param>
 public InsertNodesUndoOperation(SceneNode[] nodes)
 {
     _nodes = nodes;
     foreach (SceneNode node in nodes)
         _nodeParents.Add(node, node.Parent);
 }