Example #1
0
    private void FVmeshSingleColor(MatNode fv)
    {
        Vector3[] vertices = MatrixToVectorArray(fv.Fields["vertices"].GetValue <double[, ]>());
        int[]     faces    = MatrixTo1DArray(fv.Fields["faces"].GetValue <int[, ]>());

        Color color = GetColor(fv.Fields["color"].GetValue <double[, ]>());

        _mesh             = new Mesh();
        _mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        _mesh.vertices    = vertices;
        _mesh.triangles   = faces;
        _mesh.RecalculateNormals();

        double[,] temp = fv.Fields["opacity"].GetValue <double[, ]>();
        float _opacity = (float)temp[0, 0];

        if (_opacity < 1f)
        {
            meshInstance = Instantiate(_singelColorMeshPrefab, new Vector3(0, 0, 0), Quaternion.identity);
            meshInstance.GetComponent <Renderer>().material.SetFloat("_opacity", _opacity);
        }
        else
        {
            meshInstance = Instantiate(_opaqueSingleColorPrefab, new Vector3(0, 0, 0), Quaternion.identity);
        }

        meshInstance.GetComponent <Renderer>().material.SetColor("_color", color);
        meshInstance.transform.parent = transform;
        meshInstance.GetComponent <MeshFilter>().mesh         = _mesh;
        meshInstance.GetComponent <MeshCollider>().sharedMesh = _mesh;
    }
Example #2
0
 public void SetGridObject(int x, int y, MatNode value)
 {
     if (x >= 0 && y > 0 && x < largeur && y < hauteur)
     {
         listNode[x, y] = value;
     }
 }
Example #3
0
    private void FVmeshVertexColor(MatNode fv)
    {
        Vector3[] vertices = MatrixToVectorArray(fv.Fields["vertices"].GetValue <double[, ]>());
        int[]     faces    = MatrixTo1DArray(fv.Fields["faces"].GetValue <int[, ]>());

        double[,] col = fv.Fields["colors"].GetValue <double[, ]>();

        _mesh             = new Mesh();
        _mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        _mesh.vertices    = vertices;
        _mesh.triangles   = faces;
        _mesh.RecalculateNormals();

        UnityEngine.Gradient colMap = MatrixToColormap(fv.Fields["map"].GetValue <double[, ]>());
        Color[] vertexColors        = GetVertexColors(col, colMap, 0);
        _mesh.colors = vertexColors;

        double[,] temp = fv.Fields["opacity"].GetValue <double[, ]>();
        float _opacity = (float)temp[0, 0];

        if (_opacity < 1)
        {
            meshInstance = Instantiate(_vertexColorMeshPrefab, new Vector3(0, 0, 0), Quaternion.identity);
            meshInstance.GetComponent <Renderer>().material.SetFloat("_opacity", _opacity);
        }
        else
        {
            meshInstance = Instantiate(_opaqueVertexColorPrefab, new Vector3(0, 0, 0), Quaternion.identity);
        }

        meshInstance.transform.parent = transform;
        meshInstance.GetComponent <MeshFilter>().mesh         = _mesh; //passing the mesh to the MeshFilteere so it can be displayed
        meshInstance.GetComponent <MeshCollider>().sharedMesh = _mesh; //adding _mesh to MeshCollider so it can be hit by raycasts (and do other collider physics)
    }
Example #4
0
    //  public void setPosJ(Vector3 posJ)
    // {
    //     positionJoueur = posJ;
    // }

    // public Vector3 getPosJ()
    // {
    //     return positionJoueur;
    //}

    public void SetGridObject(Vector3 worldPosition, MatNode value)
    {
        int x, y;

        GetXY(worldPosition, out x, out y);
        SetGridObject(x, y, value);
    }
    private int CalculerLaDistanceEntreNode(MatNode a, MatNode b)
    {
        int DistanceX = Mathf.Abs(a.x - b.x);
        int DistanceY = Mathf.Abs(a.y - b.y);
        int restant   = Mathf.Abs(DistanceX - DistanceY);

        return(COUT_MOUVEMENT_DIAGONAL * Mathf.Min(DistanceX, DistanceY) + COUT_MOUVEMENT_DROIT * restant);
    }
    private void drawGraph(MatNode gr)
    {
        Color color = ColorParser.GetColor(gr.Fields["color"].GetValue <double[, ]>());

        double[,] x = gr.Fields["x"].GetValue <double[, ]>();
        double[,] y = gr.Fields["y"].GetValue <double[, ]>();

        List <Vector2[]> points = DataParser.buildPointsList(x, y);

        graphContainer.GetComponent <GraphController>().BuildGraph(points, color);
    }
Example #7
0
    public FigureDataStructList(string _path)
    {
        DataStructList = new List <FigureDataStruct>();
        MatReader inputMatReader = new MatReader(_path);
        MatNode   inputMatNode   = inputMatReader.Fields[inputMatReader.FieldNames[0]];

        foreach (var field in inputMatNode.Fields)
        {
            MatNode _struct = inputMatNode.Fields[field.Key];
            DataStructList.Add(new FigureDataStruct(_struct));    // read all variables in this node and add to list
        }
    }
    private MatNode CalculerLowerFcost(List <MatNode> listNode)
    {
        MatNode lowerFCostNode = listNode[0];

        for (int i = 0; i < listNode.Count; i++)
        {
            if (listNode[i].Fcost < lowerFCostNode.Fcost)
            {
                lowerFCostNode = listNode[i];
            }
        }

        return(lowerFCostNode);
    }
    // matType Functions
    private void FVmeshSingleColor(MatNode fv)
    {
        Vector3[] vertices = DataParser.MatrixToVectorArray(fv.Fields["vertices"].GetValue <double[, ]>());
        int[]     faces    = DataParser.MatrixTo1DArray(fv.Fields["faces"].GetValue <int[, ]>());

        GameObject meshInstance = BuilderFunctions.InstantiateMesh(vertices, faces, transform);

        Color color = ColorParser.GetColor(fv.Fields["color"].GetValue <double[, ]>());

        double[,] temp = fv.Fields["opacity"].GetValue <double[, ]>();
        float opacity = (float)temp[0, 0];

        BuilderFunctions.AddMat(opacity, meshInstance, _singleColor, _opaqueSingleColor);
        meshInstance.GetComponent <MeshRenderer>().material.SetColor("_color", color);
    }
    public List <MatNode> CalculerPathNode(MatNode endNode)
    {
        List <MatNode> chemin = new List <MatNode>();

        chemin.Add(endNode);
        MatNode nodeActuelle = endNode;

        while (nodeActuelle.cameFromNode != null)
        {
            chemin.Add(nodeActuelle.cameFromNode);
            nodeActuelle = nodeActuelle.cameFromNode;
        }
        chemin.Reverse();
        return(chemin);
    }
Example #11
0
    public void UpdateMatlabFigure()
    {
        DestroyAllChildren();
        SliderCanvas.SetActive(false);

        MatReader matFileReader = new MatReader(Application.streamingAssetsPath + Path.DirectorySeparatorChar + fileSelectionDropDown.Text);

        MatNode matFile = matFileReader.Fields[matFileReader.FieldNames[0]];

        foreach (var field in matFile.Fields)
        {
            MatNode _struct = matFile.Fields[field.Key];
            int[,] _type = _struct.Fields["type"].GetValue <int[, ]>();

            switch (_type[0, 0])
            {
            case 1:     // type 1 = FV triangulated mesh
                FVmeshVertexColor(_struct);
                break;

            case 2:
                // type 2 = 3D scatter
                scatter3(_struct);
                break;

            case 3:
                // multiple vertex color mesh
                FVmeshMultiVertColor(_struct);
                break;

            case 4:
                // inset graph;
                drawGraph(_struct);
                break;

            // should add options for multigraph
            case 5:
                // single color mesh
                FVmeshSingleColor(_struct);
                break;

            case 6:
                // set camera distance
                CamDistSetter(_struct);
                break;
            }
        }
    }
    //private MatNode CalculerLowerFcost(List<MatNode> listNode)
    //{
    //    MatNode lowerFCostNode = listNode[0];
    ////   for (int i = 0; i < listNode.Count; i++)
    //   {
    //       if (listNode[i].Fcost < lowerFCostNode.Fcost)
    //       {
    //           lowerFCostNode = listNode[i];
    //        }

    //    }

    //    return lowerFCostNode;
    //  }

    private MatNode CalculerPlusGrandFcost(List <MatNode> listNode)
    {
        //  bool plusGrandeDistanceAtteinte = true;
        MatNode plusGrandFCostNode = listNode[0];

        for (int i = 0; i < listNode.Count; i++)
        {
            if (listNode[i].Hcost >= plusGrandFCostNode.Hcost)
            {
                plusGrandFCostNode = listNode[i];
                //  plusGrandeDistanceAtteinte = false;
            }
        }
        //  if (plusGrandeDistanceAtteinte == true) atteintCasePLusEloigné = true;
        return(plusGrandFCostNode);
    }
    private List <MatNode> GetNodeVoisin(MatNode nodeActuelle)
    {
        List <MatNode> neighbourList = new List <MatNode>();

        if (nodeActuelle.x - 1 >= 0)
        {
            // Left
            neighbourList.Add(grid.GetGridObject(nodeActuelle.x - 1, nodeActuelle.y));
            // Left Down
            if (nodeActuelle.y - 1 >= 0)
            {
                neighbourList.Add(grid.GetGridObject(nodeActuelle.x - 1, nodeActuelle.y - 1));
            }
            // Left Up
            if (nodeActuelle.y + 1 < grid.GetHauteur())
            {
                neighbourList.Add(grid.GetGridObject(nodeActuelle.x - 1, nodeActuelle.y + 1));
            }
        }
        if (nodeActuelle.x + 1 < grid.GetLargueur())
        {
            // Right
            neighbourList.Add(grid.GetGridObject(nodeActuelle.x + 1, nodeActuelle.y));
            // Right Down
            if (nodeActuelle.y - 1 >= 0)
            {
                neighbourList.Add(grid.GetGridObject(nodeActuelle.x + 1, nodeActuelle.y - 1));
            }
            // Right Up
            if (nodeActuelle.y + 1 < grid.GetHauteur())
            {
                neighbourList.Add(grid.GetGridObject(nodeActuelle.x + 1, nodeActuelle.y + 1));
            }
        }
        // Down
        if (nodeActuelle.y - 1 >= 0)
        {
            neighbourList.Add(grid.GetGridObject(nodeActuelle.x, nodeActuelle.y - 1));
        }
        // Up
        if (nodeActuelle.y + 1 < grid.GetHauteur())
        {
            neighbourList.Add(grid.GetGridObject(nodeActuelle.x, nodeActuelle.y + 1));
        }

        return(neighbourList);
    }
Example #14
0
    private void FVmeshMultiVertColor(MatNode fv)
    {
        SliderCanvas.SetActive(true);

        Vector3[] vertices = MatrixToVectorArray(fv.Fields["vertices"].GetValue <double[, ]>());
        int[]     faces    = MatrixTo1DArray(fv.Fields["faces"].GetValue <int[, ]>());

        double[,] col = fv.Fields["colors"].GetValue <double[, ]>();

        _multicolorMesh             = new Mesh();
        _multicolorMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        _multicolorMesh.vertices    = vertices;
        _multicolorMesh.triangles   = faces;
        _multicolorMesh.RecalculateNormals();

        slider.maxValue = col.GetLength(1) - 1;
        slider.value    = 0;

        UnityEngine.Gradient colMap = MatrixToColormap(fv.Fields["map"].GetValue <double[, ]>());

        vertexColorList = new List <Color[]>();

        for (int i = 0; i < col.GetLength(1); i++)
        {
            vertexColorList.Add(GetVertexColors(col, colMap, i));
        }

        _multicolorMesh.colors = vertexColorList[0];

        double[,] temp = fv.Fields["opacity"].GetValue <double[, ]>();
        float _opacity = (float)temp[0, 0];

        if (_opacity < 1)
        {
            _multicolorFV = Instantiate(_vertexColorMeshPrefab, new Vector3(0, 0, 0), Quaternion.identity);
            _multicolorFV.GetComponent <Renderer>().material.SetFloat("_opacity", _opacity);
        }
        else
        {
            _multicolorFV = Instantiate(_opaqueVertexColorPrefab, new Vector3(0, 0, 0), Quaternion.identity);
        }

        _multicolorFV.transform.parent = transform;
        _multicolorFV.GetComponent <MeshFilter>().mesh         = _multicolorMesh;
        _multicolorFV.GetComponent <MeshCollider>().sharedMesh = _multicolorMesh;
    }
    private void FVmeshVertexColor(MatNode fv)
    {
        Vector3[] vertices = DataParser.MatrixToVectorArray(fv.Fields["vertices"].GetValue <double[, ]>());
        int[]     faces    = DataParser.MatrixTo1DArray(fv.Fields["faces"].GetValue <int[, ]>());

        GameObject meshInstance = BuilderFunctions.InstantiateMesh(vertices, faces, transform);

        double[,] temp = fv.Fields["opacity"].GetValue <double[, ]>();
        float opacity = (float)temp[0, 0];

        BuilderFunctions.AddMat(opacity, meshInstance, _vertexColors, _opaqueVertexColors);

        double[,] col = fv.Fields["colors"].GetValue <double[, ]>();

        List <Color[]> vertexColorList = ColorParser.GetVertexColorList(col, fv.Fields["map"].GetValue <double[, ]>());

        meshInstance.GetComponent <MeshFilter>().mesh.colors = vertexColorList[0];
    }
Example #16
0
    public MatFileReader_firstTest(MatNode matNode)
    {
        // this is a bit of a silly workaround to get a string read in to be the key "_type", but using strings as keys for _matTypes is going to maake this whole script much more readable.
        // Accord throws an error if _struct is a Matlab struct with both numeric arrays and strings
        // so type is a struct with one field. The field contains no data but the FieldName is the sting I am trying to pass.
        _type = _type = new List <string>(matNode.Fields["type"].Fields.Keys)[0];

        foreach (string str in _fieldsToRead)
        {
            if (matNode.Fields.ContainsKey(str))
            {
                _hh += str + " here\n";
                continue;
            }

            _absent += str + " missing\n";
        }
    }
 private static void HandleConnectionDictionaries(MatNode matNode)
 {
     if (matNode.Fields.ContainsKey("DirectConnections"))
     {
         foreach (string target_id in matNode.Fields["DirectConnections"].Fields.Keys)
         {
             // is this efficient to add straight to the dictionary in ShootManager...?
             // or would it be better to build a temp Dictionary here and add the whole dictionary to shootmanager...
             ShootManager.DirectConnectionDictionary.Add(target_id, DataParser.IntMatrixTo1DStringArray(matNode.Fields["DirectConnections"].Fields[target_id].GetValue <int[, ]>(), prefix: "target_"));
         }
     }
     if (matNode.Fields.ContainsKey("IndirectConnections"))
     {
         foreach (string target_id in matNode.Fields["IndirectConnections"].Fields.Keys)
         {
             ShootManager.InDirectConnectionDictionary.Add(target_id, DataParser.IntMatrixTo1DStringArray(matNode.Fields["IndirectConnections"].Fields[target_id].GetValue <int[, ]>(), prefix: "target_"));
         }
     }
 }
    public void UpdateMatlabFigure()
    {
        string    _path         = Application.streamingAssetsPath + Path.DirectorySeparatorChar + fileSelectionDropDown.Text;
        MatReader matFileReader = new MatReader(_path);

        MatNode matFile = matFileReader.Fields[matFileReader.FieldNames[0]];

        foreach (var field in matFile.Fields)
        {
            MatNode _struct = matFile.Fields[field.Key];
            // this is a bit of a silly workaround to get a string read in to be the key "_type", but using strings as keys for _matTypes is going to maake this whole script much more readable.
            // Accord throws an error if _struct is a Matlab struct with both numeric arrays and strings
            // so type is a struct with one field. The field contains no data but the FieldName is the sting I am trying to pass.
            string _type = new List <string>(_struct.Fields["type"].Fields.Keys)[0];

            MatFileReader hmm = new MatFileReader(_struct);

            _matTypes[_type](_struct);
        }
    }
    private void scatter3(MatNode sc)
    {
        GameObject scatterInstance = new GameObject("scatter3Container");

        scatterInstance.transform.parent = transform;

        Vector3[] pts = DataParser.MatrixToVectorArray(sc.Fields["vertices"].GetValue <double[, ]>());
        int[,] sz = sc.Fields["size"].GetValue <int[, ]>();

        Color color = ColorParser.GetColor(sc.Fields["color"].GetValue <double[, ]>());

        for (int i = 0; i < pts.GetLength(0); i++)
        {
            GameObject sp = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            sp.transform.position   = pts[i];
            sp.transform.localScale = new Vector3(sz[0, i], sz[0, i], sz[0, i]);
            sp.GetComponent <Renderer>().material = _scatterMat;
            sp.GetComponent <Renderer>().material.SetColor("_BaseColor", color);
            sp.transform.parent = scatterInstance.transform;
        }
    }
Example #20
0
    public MatGrid(int n_largeur, int n_hauteur, float n_dimCell, Vector3 n_origine)
    {
        largeur  = n_largeur;
        hauteur  = n_hauteur;
        dimCell  = n_dimCell;
        origine  = n_origine;
        listNode = new MatNode[largeur, hauteur];



        colliderList = GameObject.FindGameObjectsWithTag("Obstacle");

        for (int x1 = 0; x1 < listNode.GetLength(0); x1++)
        {
            for (int y2 = 0; y2 < listNode.GetLength(1); y2++)
            {
                listNode[x1, y2] = new MatNode(x1, y2);

                for (int i = 0; i < colliderList.Length; i++)
                {
                    GetXY(colliderList[i].transform.position, out int x, out int y);
                    if (x1 == x & y2 == y)
                    {
                        listNode[x, y].obstacle = true;
                    }
                }
            }
        }

        for (int x = 0; x < largeur; x++)
        {
            for (int y = 0; y < hauteur; y++)
            {
                Debug.DrawLine(Position(x, y), Position(x + 1, y), Color.white, 100f);
                Debug.DrawLine(Position(x, y), Position(x, y + 1), Color.white, 100f);
            }
        }
        Debug.DrawLine(Position(0, hauteur), Position(largeur, hauteur), Color.white, 100f);
        Debug.DrawLine(Position(largeur, 0), Position(largeur, hauteur), Color.white, 100f);
    }
Example #21
0
    private void drawGraph(MatNode gr)
    {
        GameObject _graph = Instantiate(graphPrefab, new Vector3(0, 0, 0), Quaternion.identity);

        _graph.transform.SetParent(graphContainer, false);
        UILineRenderer uILineRenderer = _graph.GetComponent <UILineRenderer>();

        Color color = GetColor(gr.Fields["color"].GetValue <double[, ]>());

        double[,] x = gr.Fields["x"].GetValue <double[, ]>();
        double[,] y = gr.Fields["y"].GetValue <double[, ]>();

        Vector2[] points = buildPointsArray(x, y, 0);

        uILineRenderer.color  = color;
        uILineRenderer.Points = points;

        if (y.GetLength(1) > 1) // if graph has more than 1 set of y values it becomes scrollable
        {
            graphList.Add(uILineRenderer);
            _graphXvalues.Add(x);
            _graphYvalues.Add(y);
        }
    }
    public FigureDataStruct(MatNode matNode)
    {
        Type = new List <string>(matNode.Fields["type"].Fields.Keys)[0]; // type MUST be defined for every input object that is why it is the only one not in an if statement

        if (Type == "ConnectionDictionary")
        {
            HandleConnectionDictionaries(matNode);
        }

        if (matNode.Fields.ContainsKey("vertices"))
        {
            Vertices = DataParser.MatrixToVectorArray(matNode.Fields["vertices"].GetValue <double[, ]>());
        }

        if (matNode.Fields.ContainsKey("faces"))
        {
            Faces = DataParser.MatrixTo1DArray(matNode.Fields["faces"].GetValue <int[, ]>());
        }

        if (matNode.Fields.ContainsKey("opacity"))
        {
            Opacity = (float)matNode.Fields["opacity"].GetValue <double[, ]>()[0, 0];
        }

        if (matNode.Fields.ContainsKey("colors"))
        {
            double[,] colorArray = matNode.Fields["colors"].GetValue <double[, ]>();
            VertColorList        = DataParser.GetVertexColorList(colorArray, matNode.Fields["map"].GetValue <double[, ]>());
        }

        if (matNode.Fields.ContainsKey("color"))
        {
            SingleColor = DataParser.GetColor(matNode.Fields["color"].GetValue <double[, ]>());
        }

        if (matNode.Fields.ContainsKey("size"))
        {
            PointSize = DataParser.MatrixTo1DArray(matNode.Fields["size"].GetValue <int[, ]>());
        }

        if (matNode.Fields.ContainsKey("camDistance"))
        {
            CamDistance = matNode.Fields["camDistance"].GetValue <int[, ]>()[0, 0];
        }

        if (matNode.Fields.ContainsKey("x"))
        {
            if (matNode.Fields.ContainsKey("y"))  // y should always be defined if x is... but just to check
            {
                GraphPointList = DataParser.buildPointsList(matNode.Fields["x"].GetValue <double[, ]>(), matNode.Fields["y"].GetValue <double[, ]>());
            }
        }

        if (matNode.Fields.ContainsKey("shootability"))
        {
            shootability = DataParser.MatrixTo1DArray(matNode.Fields["shootability"].GetValue <int[, ]>());
        }

        if (matNode.Fields.ContainsKey("id"))
        {
            id = DataParser.MatrixTo1DArray(matNode.Fields["id"].GetValue <int[, ]>());
        }
    }
    public List <MatNode> FindPath(int startX, int startY, int endX, int endY)
    {
        MatNode startNode = grid.GetGridObject(startX, startY);
        MatNode endNode   = grid.GetGridObject(endX, endY);

        openList = new List <MatNode> {
            startNode
        };
        closeList = new List <MatNode>();

        for (int x = 0; x < grid.GetLargueur(); x++)
        {
            for (int y = 0; y < grid.GetHauteur(); y++)
            {
                MatNode node = grid.GetGridObject(x, y);
                node.Gcost        = int.MaxValue;
                node.Hcost        = 0;
                node.cameFromNode = null;
                node.CalculerFcost();
            }
        }
        startNode.Gcost = 0;
        startNode.Hcost = CalculerLaDistanceEntreNode(startNode, endNode);
        startNode.CalculerFcost();

        while (openList.Count > 0)
        {
            MatNode NodeActuelle = CalculerPlusGrandFcost(openList);
            limiteDistance++;

            if (limiteDistance >= 50)
            {
                return(CalculerPathNode(NodeActuelle));                       //fin de la recherche
            }
            openList.Remove(NodeActuelle);
            closeList.Add(NodeActuelle);

            foreach (MatNode nodeVoisine in GetNodeVoisin(NodeActuelle))
            {
                if (closeList.Contains(nodeVoisine))
                {
                    continue;
                }
                if (nodeVoisine.obstacle == true)
                {
                    closeList.Add(nodeVoisine);
                    continue;
                }


                int tempGcost = NodeActuelle.Gcost + CalculerLaDistanceEntreNode(NodeActuelle, nodeVoisine);
                if (tempGcost < nodeVoisine.Gcost)
                {
                    nodeVoisine.Gcost        = tempGcost;
                    nodeVoisine.Hcost        = CalculerLaDistanceEntreNode(nodeVoisine, endNode);
                    nodeVoisine.cameFromNode = NodeActuelle;
                    nodeVoisine.CalculerFcost();

                    if (!openList.Contains(nodeVoisine))
                    {
                        openList.Add(nodeVoisine);
                    }
                }
            }
        }
        //lorsque que la openlist est vide
        return(null);
    }
 private void CamDistSetter(MatNode d)
 {
     int[,] _dist = d.Fields["camDistance"].GetValue <int[, ]>();
     CamOrbit.functions.SetCamDistance(_dist[0, 0]);
 }
Example #25
0
        /// <summary>
        ///   Creates a new <see cref="MatReader"/>.
        /// </summary>
        /// 
        /// <param name="reader">A reader for input stream containing the MAT file.</param>
        /// <param name="autoTranspose">Pass <c>true</c> to automatically transpose matrices if they 
        ///   have been stored differently from .NET's default row-major order. Default is <c>true</c>.</param>
        /// 
        public MatReader(BinaryReader reader, bool autoTranspose)
        {
            this.autoTranspose = autoTranspose;

            long startOffset = reader.BaseStream.Position;
            this.reader = reader;

            char[] title = reader.ReadChars(116);
            reader.ReadInt64(); // long subOffset
            short version = reader.ReadInt16();
            char[] endian = reader.ReadChars(2);

            int terminator = Array.IndexOf(title, '\0');
            if (terminator < 0) terminator = title.Length;

            Description = new String(title, 0, terminator).Trim();
            Version = version;
            BigEndian = endian[0] == 'M';


            if (BitConverter.IsLittleEndian && BigEndian)
                throw new NotSupportedException("The file bit ordering differs from the system architecture.");

            contents = new Dictionary<string, MatNode>();

            while (true)
            {
                long offset = reader.BaseStream.Position;

                // Read first MAT data element
                MatDataTag elementTag;
                if (!reader.Read(out elementTag))
                    return;

                // Create a new node from the current position
                MatNode node = new MatNode(this, reader, offset, elementTag, true);

                // Advance the stream to the next element (might be removed in the future)
                reader.BaseStream.Seek(offset + elementTag.NumberOfBytes + 8, SeekOrigin.Begin);

                contents.Add(node.Name, node);
            }
        }