Example #1
0
 public void AddVertex(Vertex vertex)
 {
     foreach (Vertex v in VertexSet)
     {
         if (v.Equals(vertex))
         {
             throw new ArgumentException("Vertices must have unique ids.");
         }
     }
     VertexSet.Add(vertex);
 }
Example #2
0
 public void AddEdge(Edge edge)
 {
     if (VertexSet.Contains(edge.StartVertex) && VertexSet.Contains(edge.EndVertex))
     {
         EdgeSet.Add(edge);
     }
     else
     {
         throw new ArgumentException("Could not find one or both of the specified vertices in the edge set.");
     }
 }
Example #3
0
            /// <summary>
            /// Looks for a possibly adjusted vertex value in the current set.
            /// </summary>
            /// <param name="vertex">The original vertex value.</param>
            /// <returns>The possibly adjusted vertex value.</returns>
            public XYZ FindOrAdd(XYZ vertex)
            {
                XYZ adjustedVertex = null;

                if (!VertexSet.TryGetValue(vertex, out adjustedVertex))
                {
                    adjustedVertex = vertex;
                    VertexSet.Add(adjustedVertex);
                }
                return(adjustedVertex);
            }
Example #4
0
 public override int Degree(TV vertex)
 {
     if (vertex == null)
     {
         throw new ArgumentNullException();
     }
     if (!VertexSet.Contains(vertex))
     {
         throw new ArgumentException();
     }
     return(InDegree(vertex) + OutDegree(vertex));
 }
Example #5
0
 public override bool AreAdjacent(TV v1, TV v2)
 {
     if (v1 == null || v2 == null)
     {
         throw new ArgumentNullException();
     }
     if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2))
     {
         throw new ArgumentException();
     }
     return(EdgeSet.Contains(new PairValue <TV>(v1, v2)));
 }
Example #6
0
 public void AddEdge(Vertex beginningVertex, Vertex endingVertex, Movement movement)
 {
     if (VertexSet.Contains(beginningVertex) && VertexSet.Contains(endingVertex))
     {
         Edge edge = new Edge(beginningVertex, endingVertex, movement);
         EdgeSet.Add(edge);
     }
     else
     {
         throw new ArgumentException("Could not find one or both of the specified vertices in the edge set.");
     }
 }
Example #7
0
        public override KeyValuePair <T, K> GetVertexPair(T v1Key)
        {
            if (v1Key == null)
            {
                throw new ArgumentNullException();
            }

            var vertex = VertexSet.FirstOrDefault(x => x.Key.Equals(v1Key));

            if (!VertexSet.Contains(vertex))
            {
                throw new ArgumentException();
            }

            return(vertex);
        }
 public override IEnumerable <T> AdjacentVertex(T vertex)
 {
     if (vertex == null)
     {
         throw new ArgumentNullException();
     }
     if (!VertexSet.Contains(vertex))
     {
         throw new ArgumentException();
     }
     foreach (IPairValue <T> p in EdgeSet)
     {
         if (p.GetFirst().Equals(vertex))
         {
             yield return(p.GetSecond());
         }
     }
 }
        public override bool AreAdjacent(T v1, T v2)
        {
            if (v1 is null)
            {
                throw new ArgumentNullException(nameof(v1));
            }

            if (v2 is null)
            {
                throw new ArgumentNullException(nameof(v2));
            }

            if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2))
            {
                throw new ArgumentException();
            }

            return(EdgeSet.Contains(new PairValueI <T>(v1, v2)));
        }
Example #10
0
        public override bool AddEdge(TV v1, TV v2, TK weigth)
        {
            if (v1 == null || v2 == null || weigth == null)
            {
                throw new ArgumentNullException();
            }
            if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2))
            {
                return(false);
            }
            IPairValue <TV> pair = new PairValue <TV>(v1, v2);

            if (EdgeSet.Contains(pair))
            {
                return(false);
            }
            EdgeSet.Add(pair);
            Weigths[pair] = weigth;
            return(true);
        }
Example #11
0
        public override bool AddEdge(KeyValuePair <T, K> v1, KeyValuePair <T, K> v2, K weight)
        {
            if (v1.Key == null || v2.Key == null || weight == null)
            {
                throw new ArgumentNullException();
            }
            if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2))
            {
                return(false);
            }
            IPairValue <T> pair = new PairValue <T>(v1.Key, v2.Key);

            if (EdgeSet.Contains(pair))
            {
                return(false);
            }

            EdgeSet.Add(pair);
            Weights[pair] = weight;
            return(true);
        }
Example #12
0
        public override int InDegree(TV vertex)
        {
            if (vertex == null)
            {
                throw new ArgumentNullException();
            }
            if (!VertexSet.Contains(vertex))
            {
                throw new ArgumentException();
            }
            int counter = 0;

            foreach (var pair in EdgeSet)
            {
                if (pair.GetSecond().Equals(vertex))
                {
                    counter++;
                }
            }
            return(counter);
        }
        public override int Degree(T vertex)
        {
            if (vertex == null)
            {
                throw new ArgumentNullException();
            }
            if (!VertexSet.Contains(vertex))
            {
                throw new ArgumentException();
            }
            int counter = 0;

            foreach (IPairValue <T> pair in EdgeSet)
            {
                if (pair.GetFirst().Equals(vertex))
                {
                    counter++;
                }
            }
            return(counter);
        }
Example #14
0
        public List <string> BFS(int s)
        {
            // Mark all the vertices as not
            // visited(By default set as false)
            bool[] visited = new bool[VertexSet.Count()];
            for (int i = 0; i < VertexSet.Count() - 1; i++)
            {
                visited[i] = false;
            }

            // Create a queue for BFS
            List <int>    queue = new List <int>();
            List <string> rofl  = new List <string>();

            // Mark the current node as
            // visited and enqueue it
            visited[s] = true;
            queue.Add(s);

            while (queue.Any())
            {
                s = queue.First();
                rofl.Add(VertexSet[s].ToString());
                queue.RemoveAt(queue.IndexOf(queue.First()));
                List <TV> list = AdjacentVertex(VertexSet[s]).ToList();
                foreach (var val in list)
                {
                    if (!visited[VertexSet.IndexOf(val)])
                    {
                        visited[VertexSet.IndexOf(val)] = true;
                        queue.Add(VertexSet.IndexOf(val));
                    }
                }
            }
            return(rofl);
        }
        public override bool AddEdge(T v1, T v2, K weight)
        {
            if (v1 is null)
            {
                throw new ArgumentNullException(nameof(v1));
            }

            if (v2 is null)
            {
                throw new ArgumentNullException(nameof(v2));
            }

            if (weight is null)
            {
                throw new ArgumentNullException(nameof(weight));
            }

            if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2))
            {
                return(false);
            }

            IPairValue <T> pair_1 = new PairValueI <T>(v1, v2);
            IPairValue <T> pair_2 = new PairValueI <T>(v2, v1);

            if (EdgeSet.Contains(pair_1) || EdgeSet.Contains(pair_2))
            {
                return(false);
            }

            EdgeSet.Add(pair_1);
            EdgeSet.Add(pair_2);
            Weights[pair_1] = weight;
            Weights[pair_2] = weight;
            return(true);
        }
 public void AddVertexSet(VertexSet vertexSet)
 {
     vertexDict[vertexSet.id] = vertexSet;
 }
        public void ReadVertices( Dictionary<string, VertexSet> vertexSets,
                                    XmlNode node, ColladaMeshInfo meshInfo )
        {
            string verticesId = string.Empty;
            if( node.Attributes[ "id" ] != null )
                verticesId = node.Attributes[ "id" ].Value;
            else
            {
                DebugMessage( node );
                // vertices inside of a controller don't have the id
                // Since I don't handle bone weights (the data in these),
                // just skip this for now.  TODO: Fix
                return;
            }
            VertexSet vertexSet = new VertexSet();
            vertexSet.id = verticesId;
            vertexSets[ vertexSet.id ] = vertexSet;

            foreach( XmlNode childNode in node.ChildNodes )
            {
                switch( childNode.Name )
                {
                case "input":
                    {
                        InputSourceCollection entry = ReadInput( childNode, meshInfo );
                        vertexSet.vertexEntries.Add( entry );
                        break;
                    }
                default:
                    DebugMessage( childNode );
                    break;
                }
            }
        }
Example #18
0
        private static void ParseBlock(Block block, ref MsTsShape shape, ref Vertex vertex, ref int[] intArray)
        {
            float       x, y, z;
            Vector3     point;
            KujuTokenID currentToken = KujuTokenID.error;
            Block       newBlock;
            uint        flags;

            switch (block.Token)
            {
            case KujuTokenID.shape:
                newBlock = block.ReadSubBlock(KujuTokenID.shape_header);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.volumes);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.shader_names);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.texture_filter_names);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.points);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.uv_points);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.normals);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.sort_vectors);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.colours);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.matrices);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.images);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.textures);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.light_materials);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.light_model_cfgs);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.vtx_states);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.prim_states);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.lod_controls);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.shape_header:
            case KujuTokenID.volumes:
            case KujuTokenID.texture_filter_names:
            case KujuTokenID.sort_vectors:
            case KujuTokenID.colours:
            case KujuTokenID.light_materials:
            case KujuTokenID.light_model_cfgs:
                //Unsupported stuff, so just read to the end at the minute
                block.Skip((int)block.Length());
                break;

            case KujuTokenID.vtx_state:
                flags = block.ReadUInt32();
                int  matrix1          = block.ReadInt32();
                int  lightMaterialIdx = block.ReadInt32();
                int  lightStateCfgIdx = block.ReadInt32();
                uint lightFlags       = block.ReadUInt32();
                int  matrix2          = -1;
                if ((block is BinaryBlock && block.Length() - block.Position() > 1) || (!(block is BinaryBlock) && block.Length() - block.Position() > 2))
                {
                    matrix2 = block.ReadInt32();
                }

                VertexStates vs = new VertexStates();
                vs.flags             = flags;
                vs.hierarchyID       = matrix1;
                vs.lightingMatrixID  = lightMaterialIdx;
                vs.lightingConfigIdx = lightStateCfgIdx;
                vs.lightingFlags     = lightFlags;
                vs.matrix2ID         = matrix2;
                shape.vtx_states.Add(vs);
                break;

            case KujuTokenID.vtx_states:
                int vtxStateCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (vtxStateCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.vtx_state);
                    ParseBlock(newBlock, ref shape);
                    vtxStateCount--;
                }

                break;

            case KujuTokenID.prim_state:
                flags = block.ReadUInt32();
                int   shader  = block.ReadInt32();
                int[] texIdxs = {};
                newBlock = block.ReadSubBlock(KujuTokenID.tex_idxs);
                ParseBlock(newBlock, ref shape, ref texIdxs);

                float          zBias         = block.ReadSingle();
                int            vertexStates  = block.ReadInt32();
                int            alphaTestMode = block.ReadInt32();
                int            lightCfgIdx   = block.ReadInt32();
                int            zBufferMode   = block.ReadInt32();
                PrimitiveState p             = new PrimitiveState();
                p.Name          = block.Label;
                p.Flags         = flags;
                p.Shader        = shader;
                p.Textures      = texIdxs;
                p.ZBias         = zBias;
                p.vertexStates  = vertexStates;
                p.alphaTestMode = alphaTestMode;
                p.lightCfgIdx   = lightCfgIdx;
                p.zBufferMode   = zBufferMode;
                shape.prim_states.Add(p);
                break;

            case KujuTokenID.tex_idxs:
                int texIdxCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                Array.Resize(ref intArray, texIdxCount);
                int idx = 0;
                while (texIdxCount > 0)
                {
                    intArray[idx] = block.ReadUInt16();
                    idx++;
                    texIdxCount--;
                }
                break;

            case KujuTokenID.prim_states:
                int primStateCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (primStateCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.prim_state);
                    ParseBlock(newBlock, ref shape);
                    primStateCount--;
                }

                break;

            case KujuTokenID.texture:
                int   imageIDX      = block.ReadInt32();
                int   filterMode    = (int)block.ReadUInt32();
                float mipmapLODBias = block.ReadSingle();
                uint  borderColor   = 0xff000000U;
                if (block.Length() - block.Position() > 1)
                {
                    borderColor = block.ReadUInt32();
                }

                //Unpack border color
                float r, g, b, a;
                r = borderColor % 256;
                g = (borderColor / 256) % 256;
                b = (borderColor / 256 / 256) % 256;
                a = (borderColor / 256 / 256 / 256) % 256;
                Texture t = new Texture();
                t.fileName      = shape.images[imageIDX];
                t.filterMode    = filterMode;
                t.mipmapLODBias = (int)mipmapLODBias;
                t.borderColor   = new Color32((byte)r, (byte)g, (byte)b, (byte)a);
                shape.textures.Add(t);
                break;

            case KujuTokenID.textures:
                int textureCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (textureCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.texture);
                    ParseBlock(newBlock, ref shape);
                    textureCount--;
                }

                break;

            case KujuTokenID.image:
                shape.images.Add(block.ReadString());
                break;

            case KujuTokenID.images:
                int imageCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (imageCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.image);
                    ParseBlock(newBlock, ref shape);
                    imageCount--;
                }

                break;

            case KujuTokenID.cullable_prims:
                int numPrims        = block.ReadInt32();
                int numFlatSections = block.ReadInt32();
                int numPrimIdxs     = block.ReadInt32();
                break;

            case KujuTokenID.geometry_info:
                int faceNormals      = block.ReadInt32();
                int txLightCommands  = block.ReadInt32();
                int nodeXTrilistIdxs = block.ReadInt32();
                int trilistIdxs      = block.ReadInt32();
                int lineListIdxs     = block.ReadInt32();
                nodeXTrilistIdxs = block.ReadInt32();                         //Duped, or is the first one actually something else?
                int trilists      = block.ReadInt32();
                int lineLists     = block.ReadInt32();
                int pointLists    = block.ReadInt32();
                int nodeXTrilists = block.ReadInt32();
                newBlock = block.ReadSubBlock(KujuTokenID.geometry_nodes);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.geometry_node_map);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.geometry_node_map:
                int[] geometryNodes = new int[block.ReadInt32()];
                for (int i = 0; i < geometryNodes.Length; i++)
                {
                    geometryNodes[i] = block.ReadInt32();
                }

                break;

            case KujuTokenID.geometry_node:
                int n_txLightCommands  = block.ReadInt32();
                int n_nodeXTxLightCmds = block.ReadInt32();
                int n_trilists         = block.ReadInt32();
                int n_lineLists        = block.ReadInt32();
                int n_pointLists       = block.ReadInt32();
                newBlock = block.ReadSubBlock(KujuTokenID.cullable_prims);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.geometry_nodes:
                int geometryNodeCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (geometryNodeCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.geometry_node);
                    ParseBlock(newBlock, ref shape);
                    geometryNodeCount--;
                }

                break;

            case KujuTokenID.point:
                x     = block.ReadSingle();
                y     = block.ReadSingle();
                z     = block.ReadSingle();
                point = new Vector3(x, y, z);
                shape.points.Add(point);
                break;

            case KujuTokenID.vector:
                x     = block.ReadSingle();
                y     = block.ReadSingle();
                z     = block.ReadSingle();
                point = new Vector3(x, y, z);
                shape.normals.Add(point);
                break;

            case KujuTokenID.points:
                int pointCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (pointCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.point);
                    ParseBlock(newBlock, ref shape);
                    pointCount--;
                }

                break;

            case KujuTokenID.uv_point:
                x = block.ReadSingle();
                y = block.ReadSingle();
                var uv_point = new Vector2(x, y);
                shape.uv_points.Add(uv_point);
                break;

            case KujuTokenID.uv_points:
                int uvPointCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (uvPointCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.uv_point);
                    ParseBlock(newBlock, ref shape);
                    uvPointCount--;
                }

                break;

            case KujuTokenID.matrices:
                int matrixCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (matrixCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.matrix);
                    ParseBlock(newBlock, ref shape);
                    matrixCount--;
                }
                break;

            case KujuTokenID.matrix:
                Matrix currentMatrix = new Matrix();
                currentMatrix.Name = block.Label;
                currentMatrix.A    = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle());
                currentMatrix.B    = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle());
                currentMatrix.C    = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle());
                currentMatrix.D    = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle());
                shape.matrices.Add(currentMatrix);
                break;

            case KujuTokenID.normals:
                int normalCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (normalCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.vector);
                    ParseBlock(newBlock, ref shape);
                    normalCount--;
                }

                break;

            case KujuTokenID.distance_levels_header:
                int DLevBias = block.ReadInt16();
                break;

            case KujuTokenID.distance_levels:
                int distanceLevelCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (distanceLevelCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.distance_level);
                    ParseBlock(newBlock, ref shape);
                    distanceLevelCount--;
                }

                break;

            case KujuTokenID.distance_level_header:
                newBlock = block.ReadSubBlock(KujuTokenID.dlevel_selection);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.hierarchy);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.distance_level:
                newBlock = block.ReadSubBlock(KujuTokenID.distance_level_header);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.sub_objects);
                ParseBlock(newBlock, ref shape);
                shape.LODs.Add(currentLOD);
                break;

            case KujuTokenID.dlevel_selection:
                currentLOD = new LOD(block.ReadSingle());
                break;

            case KujuTokenID.hierarchy:
                currentLOD.hierarchy = new int[block.ReadInt32()];
                for (int i = 0; i < currentLOD.hierarchy.Length; i++)
                {
                    currentLOD.hierarchy[i] = block.ReadInt32();
                }

                break;

            case KujuTokenID.lod_control:
                newBlock = block.ReadSubBlock(KujuTokenID.distance_levels_header);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.distance_levels);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.lod_controls:
                int lodCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (lodCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.lod_control);
                    ParseBlock(newBlock, ref shape);
                    lodCount--;
                }

                break;

            case KujuTokenID.primitives:
                int capacity = block.ReadInt32();                         //Count of the number of entries in the block, not the number of primitives
                while (capacity > 0)
                {
                    newBlock = block.ReadSubBlock(new KujuTokenID[] { KujuTokenID.prim_state_idx, KujuTokenID.indexed_trilist });
                    switch (newBlock.Token)
                    {
                    case KujuTokenID.prim_state_idx:
                        ParseBlock(newBlock, ref shape);
                        string txF = null;
                        try
                        {
                            txF = OpenBveApi.Path.CombineFile(currentFolder, shape.textures[shape.prim_states[shape.currentPrimitiveState].Textures[0]].fileName);
                            if (!File.Exists(txF))
                            {
                                Interface.AddMessage(MessageType.Warning, true, "Texture file " + shape.textures[shape.prim_states[shape.currentPrimitiveState].Textures[0]].fileName + " was not found.");
                                txF = null;
                            }
                        }
                        catch
                        {
                            Interface.AddMessage(MessageType.Warning, true, "Texture file path " + shape.textures[shape.prim_states[shape.currentPrimitiveState].Textures[0]].fileName + " was invalid.");
                        }
                        currentLOD.subObjects[currentLOD.subObjects.Count - 1].materials.Add(new Material(txF));
                        break;

                    case KujuTokenID.indexed_trilist:
                        ParseBlock(newBlock, ref shape);
                        break;

                    default:
                        throw new Exception("Unexpected primitive type, got " + currentToken);
                    }

                    capacity--;
                }

                break;

            case KujuTokenID.prim_state_idx:
                shape.currentPrimitiveState = block.ReadInt32();
                break;

            case KujuTokenID.indexed_trilist:
                newBlock = block.ReadSubBlock(KujuTokenID.vertex_idxs);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.normal_idxs);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.sub_object:
                newBlock = block.ReadSubBlock(KujuTokenID.sub_object_header);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.vertices);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.vertex_sets);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.primitives);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.sub_objects:
                int subObjectCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (subObjectCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.sub_object);
                    ParseBlock(newBlock, ref shape);
                    subObjectCount--;
                }

                break;

            case KujuTokenID.sub_object_header:
                currentLOD.subObjects.Add(new SubObject());
                shape.totalObjects++;
                flags = block.ReadUInt32();
                int  sortVectorIdx                = block.ReadInt32();
                int  volIdx                       = block.ReadInt32();
                uint sourceVertexFormatFlags      = block.ReadUInt32();
                uint destinationVertexFormatFlags = block.ReadUInt32();
                newBlock = block.ReadSubBlock(KujuTokenID.geometry_info);
                ParseBlock(newBlock, ref shape);

                /*
                 * Optional stuff, need to check if we're running off the end of the stream before reading each block
                 */
                if (block.Length() - block.Position() > 1)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.subobject_shaders);
                    ParseBlock(newBlock, ref shape);
                }

                if (block.Length() - block.Position() > 1)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.subobject_light_cfgs);
                    ParseBlock(newBlock, ref shape);
                }

                if (block.Length() - block.Position() > 1)
                {
                    int subObjectID = block.ReadInt32();
                }

                break;

            case KujuTokenID.subobject_light_cfgs:
                int[] subobject_light_cfgs = new int[block.ReadInt32()];
                for (int i = 0; i < subobject_light_cfgs.Length; i++)
                {
                    subobject_light_cfgs[i] = block.ReadInt32();
                }

                break;

            case KujuTokenID.subobject_shaders:
                int[] subobject_shaders = new int[block.ReadInt32()];
                for (int i = 0; i < subobject_shaders.Length; i++)
                {
                    subobject_shaders[i] = block.ReadInt32();
                }

                break;

            case KujuTokenID.vertices:
                int vertexCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (vertexCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.vertex);
                    ParseBlock(newBlock, ref shape);
                    vertexCount--;
                }

                break;

            case KujuTokenID.vertex:
                flags = block.ReadUInt32();                         //Various control variables, not supported
                int myPoint  = block.ReadInt32();                   //Index to points array
                int myNormal = block.ReadInt32();                   //Index to normals array

                Vertex v = new Vertex(shape.points[myPoint], shape.normals[myNormal]);

                uint Color1 = block.ReadUInt32();
                uint Color2 = block.ReadUInt32();
                newBlock = block.ReadSubBlock(KujuTokenID.vertex_uvs);
                ParseBlock(newBlock, ref shape, ref v);
                currentLOD.subObjects[currentLOD.subObjects.Count - 1].verticies.Add(v);
                break;

            case KujuTokenID.vertex_idxs:
                int remainingVertex = block.ReadInt32() / 3;
                while (remainingVertex > 0)
                {
                    int v1 = block.ReadInt32();
                    int v2 = block.ReadInt32();
                    int v3 = block.ReadInt32();

                    currentLOD.subObjects[currentLOD.subObjects.Count - 1].faces.Add(new Face(new int[] { v1, v2, v3 }, currentLOD.subObjects[currentLOD.subObjects.Count - 1].materials.Count - 1));
                    remainingVertex--;
                }

                break;

            case KujuTokenID.vertex_set:
                int       vertexStateIndex    = block.ReadInt32();                              //Index to the vtx_states member
                int       hierarchy           = shape.vtx_states[vertexStateIndex].hierarchyID; //Now pull the hierachy ID out
                int       setStartVertexIndex = block.ReadInt32();                              //First vertex
                int       setVertexCount      = block.ReadInt32();                              //Total number of vert
                VertexSet vts = new VertexSet();
                vts.hierarchyIndex = hierarchy;
                vts.startVertex    = setStartVertexIndex;
                vts.numVerticies   = setVertexCount;
                currentLOD.subObjects[currentLOD.subObjects.Count - 1].vertexSets.Add(vts);
                break;

            case KujuTokenID.vertex_sets:
                int vertexSetCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (vertexSetCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.vertex_set);
                    ParseBlock(newBlock, ref shape);
                    vertexSetCount--;
                }

                //We now need to transform our verticies
                currentLOD.subObjects[currentLOD.subObjects.Count - 1].TransformVerticies(shape.matrices);
                break;

            case KujuTokenID.vertex_uvs:
                int[] vertex_uvs = new int[block.ReadInt32()];
                for (int i = 0; i < vertex_uvs.Length; i++)
                {
                    vertex_uvs[i] = block.ReadInt32();
                }

                //Looks as if vertex_uvs should always be of length 1, thus:
                vertex.TextureCoordinates = shape.uv_points[vertex_uvs[0]];
                break;
            }
        }